Every API here is available over the APIs.io API and to AI agents over MCP.
{"openapi":"3.1.0","info":{"title":"Bronjoy","version":"0.0.1"},"servers":[{"url":"https://api.bronjoy.com/api"}],"paths":{"/org/announcements":{"get":{"operationId":"announcements.index","summary":"List announcements for the organization","tags":["Announcement"],"parameters":[{"name":"active","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Paginated set of `AnnouncementResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AnnouncementResource"}},"links":{"type":"object","properties":{"first":{"type":["string","null"]},"last":{"type":["string","null"]},"prev":{"type":["string","null"]},"next":{"type":["string","null"]}},"required":["first","last","prev","next"]},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"from":{"type":["integer","null"]},"last_page":{"type":"integer"},"links":{"type":"array","description":"Generated paginator links.","items":{"type":"object","properties":{"url":{"type":["string","null"]},"label":{"type":"string"},"active":{"type":"boolean"}},"required":["url","label","active"]}},"path":{"type":["string","null"],"description":"Base path for paginator generated URLs."},"per_page":{"type":"integer","description":"Number of items shown per page."},"to":{"type":["integer","null"],"description":"Number of the last item in the slice."},"total":{"type":"integer","description":"Total number of items being paginated."}},"required":["current_page","from","last_page","links","path","per_page","to","total"]}},"required":["data","links","meta"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}},"post":{"operationId":"announcements.store","summary":"Create a new announcement","tags":["Announcement"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAnnouncementRequest"}}}},"responses":{"200":{"description":"`AnnouncementResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnnouncementResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/announcements/{announcement}":{"get":{"operationId":"announcements.show","summary":"Get a single announcement","tags":["Announcement"],"parameters":[{"name":"announcement","in":"path","required":true,"description":"The announcement ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"`AnnouncementResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnnouncementResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}},"put":{"operationId":"announcements.update","summary":"Update an announcement","tags":["Announcement"],"parameters":[{"name":"announcement","in":"path","required":true,"description":"The announcement ID","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAnnouncementRequest"}}}},"responses":{"200":{"description":"`AnnouncementResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AnnouncementResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"},"422":{"$ref":"#/components/responses/ValidationException"}}},"delete":{"operationId":"announcements.destroy","summary":"Delete an announcement","tags":["Announcement"],"parameters":[{"name":"announcement","in":"path","required":true,"description":"The announcement ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Announcement deleted"]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/org/appointments":{"get":{"operationId":"appointment.index","tags":["Appointment"],"parameters":[{"name":"status[]","in":"query","schema":{"type":"array","enum":["pending","confirmed","completed","cancelled","no_show"],"items":{"type":"string","enum":["pending","confirmed","completed","cancelled","no_show"]}}},{"name":"payment_status[]","in":"query","schema":{"type":"array","enum":["unpaid","paid","refunded"],"items":{"type":"string","enum":["unpaid","paid","refunded"]}}},{"name":"staff_id[]","in":"query","schema":{"type":"array","items":{"type":"integer"}}},{"name":"service_id[]","in":"query","schema":{"type":"array","items":{"type":"integer"}}},{"name":"search","in":"query","schema":{"type":["string","null"],"maxLength":255}},{"name":"from","in":"query","schema":{"type":["string","null"],"format":"date-time"}},{"name":"to","in":"query","schema":{"type":["string","null"],"format":"date-time"}},{"name":"my_appointments","in":"query","schema":{"type":["boolean","null"]}},{"name":"page","in":"query","schema":{"type":["integer","null"],"minimum":1}},{"name":"per_page","in":"query","schema":{"type":["integer","null"],"minimum":1,"maximum":1000}},{"name":"sort_by","in":"query","schema":{"type":["string","null"],"enum":["id","start_time","status","payment_status","created_at"]}},{"name":"sort_order","in":"query","schema":{"type":["string","null"],"enum":["asc","desc"]}}],"responses":{"200":{"description":"Paginated set of `AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppointmentResource"}},"links":{"type":"object","properties":{"first":{"type":["string","null"]},"last":{"type":["string","null"]},"prev":{"type":["string","null"]},"next":{"type":["string","null"]}},"required":["first","last","prev","next"]},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"from":{"type":["integer","null"]},"last_page":{"type":"integer"},"links":{"type":"array","description":"Generated paginator links.","items":{"type":"object","properties":{"url":{"type":["string","null"]},"label":{"type":"string"},"active":{"type":"boolean"}},"required":["url","label","active"]}},"path":{"type":["string","null"],"description":"Base path for paginator generated URLs."},"per_page":{"type":"integer","description":"Number of items shown per page."},"to":{"type":["integer","null"],"description":"Number of the last item in the slice."},"total":{"type":"integer","description":"Total number of items being paginated."}},"required":["current_page","from","last_page","links","path","per_page","to","total"]}},"required":["data","links","meta"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}},"post":{"operationId":"appointment.store","tags":["Appointment"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreAppointmentRequest"}}}},"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/appointments/pending":{"get":{"operationId":"appointment.pending","tags":["Appointment"],"parameters":[{"name":"per_page","in":"query","schema":{"type":"string","default":20}}],"responses":{"200":{"description":"Paginated set of `AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppointmentResource"}},"links":{"type":"object","properties":{"first":{"type":["string","null"]},"last":{"type":["string","null"]},"prev":{"type":["string","null"]},"next":{"type":["string","null"]}},"required":["first","last","prev","next"]},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"from":{"type":["integer","null"]},"last_page":{"type":"integer"},"links":{"type":"array","description":"Generated paginator links.","items":{"type":"object","properties":{"url":{"type":["string","null"]},"label":{"type":"string"},"active":{"type":"boolean"}},"required":["url","label","active"]}},"path":{"type":["string","null"],"description":"Base path for paginator generated URLs."},"per_page":{"type":"integer","description":"Number of items shown per page."},"to":{"type":["integer","null"],"description":"Number of the last item in the slice."},"total":{"type":"integer","description":"Total number of items being paginated."}},"required":["current_page","from","last_page","links","path","per_page","to","total"]}},"required":["data","links","meta"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}}},"/org/appointments/calendar":{"get":{"operationId":"appointment.calendar","tags":["Appointment"],"parameters":[{"name":"start","in":"query","required":true,"schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","required":true,"schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Array of `AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AppointmentResource"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/appointments/batch-update":{"post":{"operationId":"appointment.batchUpdate","tags":["Appointment"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUpdateAppointmentsRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"updated_count":{"type":"string"}},"required":["message","updated_count"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/appointments/batch-destroy":{"post":{"operationId":"appointment.batchDestroy","tags":["Appointment"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchDestroyAppointmentsRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"deleted_count":{"type":"string"}},"required":["message","deleted_count"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/appointments/{appointment}":{"get":{"operationId":"appointment.show","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}},"put":{"operationId":"appointment.update","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAppointmentRequest"}}}},"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"},"422":{"$ref":"#/components/responses/ValidationException"}}},"delete":{"operationId":"appointment.destroy","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Appointment deleted"]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/org/appointments/{appointment}/submit":{"post":{"operationId":"appointment.submit","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/org/appointments/{appointment}/cancel":{"post":{"operationId":"appointment.cancel","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelAppointmentRequest"}}}},"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/appointments/{appointment}/reschedule":{"post":{"operationId":"appointment.reschedule","tags":["Appointment"],"parameters":[{"name":"appointment","in":"path","required":true,"description":"The appointment ID","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RescheduleAppointmentRequest"}}}},"responses":{"200":{"description":"`AppointmentResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AppointmentResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/schedule":{"get":{"operationId":"availability.schedule","summary":"Get unified schedule - both recurring availabilities and one-time exceptions\nSupports my_schedule=true to filter to current user's schedule only","tags":["Availability"],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"string"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}},"post":{"operationId":"availability.store","summary":"Store a new schedule entry","tags":["Availability"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreScheduleEntryRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]},"message":{"type":"string","enum":["One-time availability created"]}},"required":["data","message"]},{"type":"object","properties":{"data":{"type":"array","prefixItems":[{"type":"object","properties":{"id":{"type":"string"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]}],"minItems":1,"maxItems":1,"additionalItems":false},"message":{"type":"string","enum":["Recurring availability created"]}},"required":["data","message"]}]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/schedule/{id}":{"put":{"operationId":"availability.update","summary":"Update a schedule entry","tags":["Availability"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScheduleEntryRequest"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","enum":["Exception updated"]},"data":{"type":"object","properties":{"id":{"type":"integer"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","enum":["Availability updated"]},"data":{"type":"object","properties":{"id":{"type":"integer"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","enum":["Converted to recurring availability"]},"data":{"type":"object","properties":{"id":{"type":"string"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","enum":["Converted to one-time availability"]},"data":{"type":"object","properties":{"id":{"type":"string"},"is_recurring":{"type":"boolean"}},"required":["id","is_recurring"]}},"required":["message","data"]}]}}}},"400":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["day_of_week is required for recurring entries"]}},"required":["error"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Entry not found"]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"}}},"delete":{"operationId":"availability.destroy","summary":"Delete a schedule entry","tags":["Availability"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},{"name":"is_recurring","in":"query","required":true,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Availability deleted","Exception deleted"]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"404":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Entry not found"]}},"required":["message"]}}}},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/availability":{"get":{"operationId":"availability.index","tags":["Availability"],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}},"put":{"operationId":"availability.legacyUpdate","tags":["Availability"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"availabilities":{"type":"array","items":{"type":"object","properties":{"staff_id":{"type":["integer","null"]},"service_id":{"type":["integer","null"]},"day_of_week":{"type":"integer","minimum":0,"maximum":6},"start_time":{"type":"string"},"end_time":{"type":"string"},"is_available":{"type":"boolean"}},"required":["day_of_week","start_time","end_time"]}}},"required":["availabilities"]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","prefixItems":[{"type":"string"}],"minItems":1,"maxItems":1,"additionalItems":false},"message":{"type":"string","enum":["Availability updated"]}},"required":["data","message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/availability/exceptions":{"get":{"operationId":"availability.exceptions","tags":["Availability"],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}},"post":{"operationId":"availability.storeException","tags":["Availability"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"staff_id":{"type":["integer","null"]},"service_id":{"type":["integer","null"]},"date":{"type":"string","format":"date"},"start_time":{"type":["string","null"]},"end_time":{"type":["string","null"]},"is_available":{"type":"boolean"},"reason":{"type":["string","null"],"maxLength":255}},"required":["date"]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/organization-profiles/{slug}/booking-requests":{"post":{"operationId":"bookingRequest.store","description":"Unclaimed venues only: Bronjoy passes the request on to the venue by\nphone. A claimed venue answers 409 — it has real online booking. The same\nphone asking for the same venue again within 24 hours gets the first\nrequest back (200) instead of a duplicate.\n\nPublic endpoint, published profiles only. Guarded by Turnstile (when\nconfigured) and the `booking-request` limiter.","summary":"Leave a booking request on a venue that takes no online bookings yet","tags":["BookingRequest"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitBookingRequestRequest"}}}},"responses":{"201":{"description":"201 for a new request; 200 when a duplicate returns the first one.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string","enum":["new","forwarded","booked","no_answer","declined","spam"]},"telegram_ref":{"type":"string"}},"required":["id","status","telegram_ref"]}}}},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/branches":{"get":{"operationId":"branches.index","tags":["Branch"],"responses":{"200":{"description":"Paginated set of `BranchResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BranchResource"}},"links":{"type":"object","properties":{"first":{"type":["string","null"]},"last":{"type":["string","null"]},"prev":{"type":["string","null"]},"next":{"type":["string","null"]}},"required":["first","last","prev","next"]},"meta":{"type":"object","properties":{"current_page":{"type":"integer"},"from":{"type":["integer","null"]},"last_page":{"type":"integer"},"links":{"type":"array","description":"Generated paginator links.","items":{"type":"object","properties":{"url":{"type":["string","null"]},"label":{"type":"string"},"active":{"type":"boolean"}},"required":["url","label","active"]}},"path":{"type":["string","null"],"description":"Base path for paginator generated URLs."},"per_page":{"type":"integer","description":"Number of items shown per page."},"to":{"type":["integer","null"],"description":"Number of the last item in the slice."},"total":{"type":"integer","description":"Total number of items being paginated."}},"required":["current_page","from","last_page","links","path","per_page","to","total"]}},"required":["data","links","meta"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"}}},"post":{"operationId":"branches.store","tags":["Branch"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBranchRequest"}}}},"responses":{"200":{"description":"`BranchResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BranchResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"upgrade_required":{"type":"boolean"}},"required":["message","upgrade_required"]}}}},"422":{"$ref":"#/components/responses/ValidationException"}}}},"/org/branches/{branch}":{"get":{"operationId":"branches.show","tags":["Branch"],"parameters":[{"name":"branch","in":"path","required":true,"description":"The branch ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"`BranchResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BranchResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}},"put":{"operationId":"branches.update","tags":["Branch"],"parameters":[{"name":"branch","in":"path","required":true,"description":"The branch ID","schema":{"type":"integer"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBranchRequest"}}}},"responses":{"200":{"description":"`BranchResource`","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BranchResource"}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"},"422":{"$ref":"#/components/responses/ValidationException"}}},"delete":{"operationId":"branches.destroy","tags":["Branch"],"parameters":[{"name":"branch","in":"path","required":true,"description":"The branch ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Deleted"]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/calendar/callback/google":{"get":{"operationId":"calendar.callback.google","summary":"Handle Google OAuth callback.\nExchanges authorization code for tokens and redirects back to frontend","tags":["CalendarCallback"],"parameters":[{"name":"code","in":"query","schema":{"type":"string"}},{"name":"state","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/org/calendar/connections":{"get":{"operationId":"calendarConnection.index","summary":"List the current staff member's calendar connections","tags":["CalendarConnection"],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CalendarConnectionResource"}}},"required":["data"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Staff profile not found."]}},"required":["message"]}}}}}}},"/org/calendar/auth-url":{"get":{"operationId":"calendarConnection.getAuthUrl","summary":"Generate the OAuth authorization URL for connecting a provider","tags":["CalendarConnection"],"parameters":[{"name":"provider","in":"query","schema":{"type":"string","default":"google"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":["string","null"]}},"required":["url"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Staff profile not found."]}},"required":["message"]}}}},"422":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Unsupported calendar provider."]}},"required":["message"]}}}}}}},"/org/calendar/feed-url":{"get":{"operationId":"calendarConnection.getFeedUrl","summary":"Get the iCal feed URL for the current staff member","tags":["CalendarConnection"],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"feed_url":{"type":"string"}},"required":["feed_url"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"404":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Staff profile not found."]}},"required":["message"]}}}}}}},"/org/calendar/connections/{connection}":{"delete":{"operationId":"calendarConnection.disconnect","summary":"Disconnect a calendar connection and revoke tokens","tags":["CalendarConnection"],"parameters":[{"name":"connection","in":"path","required":true,"description":"The connection ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Calendar disconnected."]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Not authorized."]}},"required":["message"]}}}},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/org/calendar/connections/{connection}/toggle":{"patch":{"operationId":"calendarConnection.toggleSync","summary":"Toggle push or pull sync for a connection","tags":["CalendarConnection"],"parameters":[{"name":"connection","in":"path","required":true,"description":"The connection ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CalendarConnectionResource"},"message":{"type":"string","enum":["Sync settings updated."]}},"required":["data","message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Not authorized."]}},"required":["message"]}}}},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/org/calendar/connections/{connection}/sync":{"post":{"operationId":"calendarConnection.syncNow","summary":"Trigger an immediate sync for a calendar connection","tags":["CalendarConnection"],"parameters":[{"name":"connection","in":"path","required":true,"description":"The connection ID","schema":{"type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Sync queued."]}},"required":["message"]}}}},"401":{"$ref":"#/components/responses/AuthenticationException"},"403":{"description":"","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","enum":["Not authorized."]}},"required":["message"]}}}},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/calendar/feed/{token}.ics":{"get":{"operationId":"calendar.feed","summary":"Serve the iCal feed for a staff member.\nThe token in the URL authenticates the request — no login needed","tags":["CalendarFeed"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"text/calendar; charset=utf-8":{"schema":{"type":"string"}}},"headers":{"Content-Disposition":{"schema":{"type":"string","enum":["attachment; filename=\"bronjoy-calendar.ics\""]}},"Cache-Control":{"schema":{"type":"string","enum":["no-cache, must-revalidate"]}}}},"404":{"$ref":"#/components/responses/ModelNotFoundException"}}}},"/categories":{"get":{"operationId":
# --- truncated at 32 KB (375 KB total) ---
# Full source: https://artifacts.apis.io/bronjoy-com/openapi/_original/bronjoy-com-api-spec-openapi.json