{"openapi":"3.1.0","info":{"title":"AIPickUp4U","version":"1","description":"Manage bookings for your AIPickUp4U shop. Docs: https://www.aipickup4u.com/developers"},"servers":[{"url":"https://app.aipickup4u.com"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/availability":{"get":{"parameters":[{"name":"date","in":"query","required":true,"schema":{"type":"string","format":"date","title":"Date"},"description":"Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},{"name":"time_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Time From"},"description":"Earliest start, HH:MM. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},{"name":"time_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"time"},{"type":"null"}],"title":"Time To"},"description":"Latest start, HH:MM. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},{"name":"service_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Name"},"description":"Service name; matches the names returned by listServices. If it matches nothing it is echoed back in `unresolved`."},{"name":"preferred_resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preferred Resource"},"description":"Optional staff, table or room name from listResources. Unmatched names are echoed back in `unresolved`."},{"name":"party_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":1,"title":"Party Size"},"description":"Number of guests or animals. Default 1."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":5,"title":"Limit"},"description":"Maximum number of slots to return (1-50). Default 5."},{"name":"exclude_booking","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Exclude Booking"},"description":"When checking times to reschedule a booking, pass its id so its own slot counts as free."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getAvailability","summary":"Open times for a date and service.","description":"Read-only. Does not hold the slot. Requires the `read` scope."}},"/api/v1/blocked-slots":{"get":{"parameters":[{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date From"},"description":"First date to include. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date To"},"description":"Last date to include. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BlockOut"},"title":"Response List Blocks Api V1 Blocked Slots Get"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listBlockedSlots","summary":"Windows closed to new bookings.","description":"Read-only. Requires the `read` scope."},"post":{"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency-Key"},"description":"Retries with the same key and same request return the original result; the same key with a different request is rejected with 422."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A request with the same Idempotency-Key is still in flight (idempotency_conflict). Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"blockSlot","summary":"Stop new bookings in a window.","description":"Stops new bookings in that window; existing bookings stay. Ask the owner to confirm before calling. Requires the `config:write` scope.","x-requires-confirmation":true}},"/api/v1/blocked-slots/{block_id}":{"delete":{"parameters":[{"name":"block_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Block Id"},"description":"Blocked-window id from listBlockedSlots or blockSlot."}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"unblockSlot","summary":"Reopen a closed window.","description":"Reopens the window for new bookings. Requires the `config:write` scope."}},"/api/v1/bookings":{"get":{"parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"},"description":"Only bookings on this date. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"description":"Only bookings with this status. One of: confirmed, cancelled, completed, no_show, pending_credit_check (held slot awaiting the front desk's confirmation; no confirmation text sent)."},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"},"description":"Page number, starting at 1."},{"name":"size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Size"},"description":"Page size (1-100). Default 20."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page_BookingOut_"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listBookings","summary":"List bookings by date or status.","description":"Read-only. Does not contact the customer. Requires the `read` scope."},"post":{"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency-Key"},"description":"Retries with the same key and same request return the original result; the same key with a different request is rejected with 422."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingOut"}}}},"400":{"description":"A booking rule failed. The code names the rule: bad_time, outside_hours, slot_blocked, skill_mismatch, capacity_mismatch, contact_required, too_soon or out_of_service_area.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested time is taken (conflict), or a request with the same Idempotency-Key is still in flight (idempotency_conflict; retry shortly). For createBooking, a concurrent retry may also surface as conflict; retrying with the same Idempotency-Key returns the original result if the first request succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"createBooking","summary":"Book a customer in.","description":"Creates a booking and texts the customer a confirmation. Requires the `bookings:write` scope."}},"/api/v1/bookings/{booking_id}":{"get":{"parameters":[{"name":"booking_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Booking Id"},"description":"Booking id from listBookings or createBooking."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getBooking","summary":"Get one booking.","description":"Read-only. Requires the `read` scope."},"delete":{"parameters":[{"name":"booking_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Booking Id"},"description":"Booking id from listBookings or createBooking."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency-Key"},"description":"Retries with the same key and same request return the original result; the same key with a different request is rejected with 422."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A request with the same Idempotency-Key is still in flight (idempotency_conflict). Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"cancelBooking","summary":"Cancel a booking.","description":"Cancels the booking and texts the customer. Cannot be undone. Ask the owner to confirm before calling. Requires the `bookings:write` scope.","x-requires-confirmation":true}},"/api/v1/bookings/{booking_id}/reschedule":{"post":{"parameters":[{"name":"booking_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Booking Id"},"description":"Booking id from listBookings or createBooking."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency-Key"},"description":"Retries with the same key and same request return the original result; the same key with a different request is rejected with 422."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingReschedule"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingOut"}}}},"400":{"description":"A booking rule failed. The code names the rule: bad_time, outside_hours, slot_blocked, skill_mismatch, capacity_mismatch, contact_required, too_soon or out_of_service_area.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested time is taken (conflict), or a request with the same Idempotency-Key is still in flight (idempotency_conflict; retry shortly). For createBooking, a concurrent retry may also surface as conflict; retrying with the same Idempotency-Key returns the original result if the first request succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"rescheduleBooking","summary":"Move a booking.","description":"Moves the booking and texts the customer the new time. Ask the owner to confirm before calling. Call getAvailability with exclude_booking first. Requires the `bookings:write` scope.","x-requires-confirmation":true}},"/api/v1/resources":{"get":{"parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"},"description":"Also list deactivated resources. Default false."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ResourceOut"},"title":"Response List Resources Api V1 Resources Get"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listResources","summary":"Staff, tables or rooms.","description":"Read-only. Requires the `read` scope."}},"/api/v1/services":{"get":{"parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"},"description":"Also list deactivated services. Default false."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ServiceOut"},"title":"Response List Services Api V1 Services Get"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listServices","summary":"Services the shop offers.","description":"Read-only. Requires the `read` scope."}},"/api/v1/stats":{"get":{"parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"},"description":"Statistics for this date. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getStats","summary":"Today's numbers.","description":"Read-only. Requires the `read` scope."}},"/api/v1/menu":{"get":{"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Menu Api V1 Menu Get"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getMenu","summary":"The menu (food businesses).","description":"Read-only. Requires the `read` scope."}},"/api/v1/orders":{"get":{"parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date"},"description":"Only orders picked up on this date. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrderOut"},"title":"Response List Orders Api V1 Orders Get"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"listOrders","summary":"Orders for a date.","description":"Read-only. Requires the `read` scope."}},"/api/v1/orders/{order_id}":{"patch":{"parameters":[{"name":"order_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Order Id"},"description":"Order id from listOrders."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Idempotency-Key"},"description":"Retries with the same key and same request return the original result; the same key with a different request is rejected with 422."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderStatusUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderOut"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The id does not exist in this shop (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A request with the same Idempotency-Key is still in flight (idempotency_conflict). Retry shortly.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"updateOrderStatus","summary":"Change an order's status.","description":"Changes the order status. Cancelling texts the customer. Requires the `orders:write` scope."}},"/api/v1/connector/me":{"get":{"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectorMe"}}}},"401":{"description":"Missing, unknown or revoked key (invalid_key, key_revoked).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The key may not do this (scope_missing, plan_required, trade_not_supported).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Invalid input (validation_error), or an Idempotency-Key reused for a different request (idempotency_key_reused).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited (rate_limited). Wait for the Retry-After header before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"API access is temporarily switched off (connector_disabled). Retry later.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"operationId":"getConnectorMe","summary":"Who am I: shop, timezone, today, hours, this key's scopes.","description":"Read-only. Requires the `read` scope."}}},"components":{"schemas":{"AvailabilityOut":{"properties":{"available":{"type":"boolean","title":"Available"},"on_date":{"type":"string","format":"date","title":"On Date","description":"The date that was checked."},"slots":{"items":{"$ref":"#/components/schemas/SlotOut"},"type":"array","title":"Slots"},"unresolved":{"items":{"type":"string"},"type":"array","title":"Unresolved","description":"Names in the request that matched nothing."}},"type":"object","required":["available","on_date","slots"],"title":"AvailabilityOut"},"BlockCreate":{"properties":{"block_date":{"type":"string","format":"date","title":"Block Date","description":"Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},"start_time":{"type":"string","format":"time","title":"Start Time","default":"00:00:00","description":"Start of the window, HH:MM. Default 00:00. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"end_time":{"type":"string","format":"time","title":"End Time","default":"23:59:59","description":"End of the window, HH:MM. Default 23:59:59. Must be after start_time (otherwise 422). Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"resource_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Resource Id","description":"Resource to close. Id from getAvailability `slots[].resource_id` or listResources. null closes the whole shop."},"reason":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Reason","description":"Optional reason, for the owner's reference."}},"type":"object","required":["block_date"],"title":"BlockCreate"},"BlockOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"block_date":{"type":"string","format":"date","title":"Block Date"},"start_time":{"type":"string","format":"time","title":"Start Time"},"end_time":{"type":"string","format":"time","title":"End Time"},"resource_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Resource Id","description":"null means the whole shop is closed for the window."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["id","block_date","start_time","end_time","resource_id","reason"],"title":"BlockOut"},"BookingCreate":{"properties":{"resource_id":{"type":"string","format":"uuid","title":"Resource Id","description":"Id from getAvailability `slots[].resource_id` or listResources."},"booking_date":{"type":"string","format":"date","title":"Booking Date","description":"Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},"start_time":{"type":"string","format":"time","title":"Start Time","description":"Start, HH:MM. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"guest_name":{"type":"string","maxLength":200,"minLength":1,"title":"Guest Name","description":"Customer's name."},"guest_phone":{"type":"string","maxLength":32,"minLength":1,"title":"Guest Phone","description":"Customer's mobile in E.164 (+1XXXXXXXXXX); US/Canada. The customer receives SMS at this number."},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id","description":"Id from listServices. Optional for restaurants."},"party_size":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Party Size","default":1,"description":"Number of guests. Default 1."},"pet_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pet Name"},"pet_breed":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pet Breed"},"pet_size":{"anyOf":[{"type":"string","pattern":"^(small|medium|large)$"},{"type":"null"}],"title":"Pet Size","description":"Pet grooming only: small, medium or large."},"address":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Address","description":"Service address, for businesses that travel to the customer."},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Free-text note for the shop."}},"type":"object","required":["resource_id","booking_date","start_time","guest_name","guest_phone"],"title":"BookingCreate"},"BookingOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"resource_id":{"type":"string","format":"uuid","title":"Resource Id"},"service_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Service Id"},"booking_date":{"type":"string","format":"date","title":"Booking Date","description":"Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},"start_time":{"type":"string","format":"time","title":"Start Time","description":"Start, HH:MM:SS. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"end_time":{"type":"string","format":"time","title":"End Time","description":"End, HH:MM:SS. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"guest_name":{"type":"string","title":"Guest Name"},"guest_phone":{"type":"string","title":"Guest Phone"},"party_size":{"type":"integer","title":"Party Size"},"pet_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pet Name"},"pet_breed":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pet Breed"},"pet_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pet Size"},"status":{"type":"string","title":"Status","description":"One of: confirmed, cancelled, completed, no_show, pending_credit_check (held slot awaiting the front desk's confirmation; no confirmation text sent)."},"confirmation_code":{"type":"string","title":"Confirmation Code","description":"6-character code the customer can read out."},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"source":{"type":"string","title":"Source","description":"One of: ai_phone, manual, walk_in, google_rwg. Bookings created through this API show `manual`."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the booking was created (UTC timestamp)."}},"type":"object","required":["id","resource_id","service_id","booking_date","start_time","end_time","guest_name","guest_phone","party_size","pet_name","pet_breed","pet_size","status","confirmation_code","notes","source","created_at"],"title":"BookingOut"},"BookingReschedule":{"properties":{"booking_date":{"type":"string","format":"date","title":"Booking Date","description":"New date. Shop-local calendar date, YYYY-MM-DD, in the shop's timezone. Use `today` from getConnectorMe for today; do not compute it yourself."},"start_time":{"type":"string","format":"time","title":"Start Time","description":"New start, HH:MM. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"resource_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Resource Id","description":"Optional new resource. Id from getAvailability `slots[].resource_id` or listResources. Omit to keep the current one."}},"type":"object","required":["booking_date","start_time"],"title":"BookingReschedule"},"ConnectorMe":{"properties":{"shop_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Shop Name"},"business_type":{"type":"string","title":"Business Type"},"timezone":{"type":"string","title":"Timezone","description":"IANA timezone of the shop. All dates and times use it."},"today":{"type":"string","format":"date","title":"Today","description":"Today's date in the shop's timezone. Use this as 'today'."},"hours":{"items":{"$ref":"#/components/schemas/HoursOut"},"type":"array","title":"Hours"},"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes","description":"Scopes granted to this key."},"plan":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plan","description":"The shop's subscription plan, or null."}},"type":"object","required":["shop_name","business_type","timezone","today","hours","scopes","plan"],"title":"ConnectorMe"},"ErrorResponse":{"type":"object","title":"ErrorResponse","description":"Error body. `error.code` is stable and machine-readable; `error.message` is for people. Booking-rule failures use the lowercase rule name as the code (for example conflict, slot_blocked, outside_hours, bad_time, capacity_mismatch, skill_mismatch, too_soon) with HTTP 400, or 409 for conflict. Unknown ids return 404 not_found.","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"One of: invalid_key, key_revoked, plan_required, trade_not_supported, scope_missing, rate_limited, connector_disabled, idempotency_key_reused, idempotency_conflict, validation_error, not_found."},"message":{"type":"string"}}}}},"HoursOut":{"properties":{"day_of_week":{"type":"integer","title":"Day Of Week","description":"0 = Sunday, 1 = Monday, ... 6 = Saturday. It is the day the shop opens."},"open":{"type":"string","title":"Open","description":"Opening time, HH:MM, shop-local."},"close":{"type":"string","title":"Close","description":"Closing time, HH:MM, shop-local. A close at or before `open` means the shop closes after midnight, on the next day."}},"type":"object","required":["day_of_week","open","close"],"title":"HoursOut"},"OrderItemOptionOut":{"properties":{"name":{"type":"string","title":"Name"},"price_delta":{"type":"string","title":"Price Delta","description":"Decimal string in the shop's currency."}},"type":"object","required":["name","price_delta"],"title":"OrderItemOptionOut"},"OrderItemOut":{"properties":{"name":{"type":"string","title":"Name"},"quantity":{"type":"integer","title":"Quantity"},"unit_price":{"type":"string","title":"Unit Price","description":"Decimal string in the shop's currency."},"line_total":{"type":"string","title":"Line Total","description":"Decimal string in the shop's currency."},"options":{"items":{"$ref":"#/components/schemas/OrderItemOptionOut"},"type":"array","title":"Options"}},"type":"object","required":["name","quantity","unit_price","line_total","options"],"title":"OrderItemOut"},"OrderOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"pickup_code":{"type":"string","title":"Pickup Code","description":"Code the customer gives at pickup."},"guest_name":{"type":"string","title":"Guest Name"},"guest_phone":{"type":"string","title":"Guest Phone"},"pickup_at":{"type":"string","title":"Pickup At","description":"Pickup time, ISO 8601 timestamp in UTC. Convert it to the shop's timezone (getConnectorMe.timezone) before reading it out."},"status":{"type":"string","title":"Status","description":"One of: placed, ready, collected, cancelled. Allowed changes: placed to ready or cancelled, ready to collected or cancelled."},"total":{"type":"string","title":"Total","description":"Decimal string in the shop's currency."},"source":{"type":"string","title":"Source"},"items":{"items":{"$ref":"#/components/schemas/OrderItemOut"},"type":"array","title":"Items"}},"type":"object","required":["id","pickup_code","guest_name","guest_phone","pickup_at","status","total","source","items"],"title":"OrderOut"},"OrderStatusUpdate":{"properties":{"status":{"type":"string","enum":["placed","ready","collected","cancelled"],"title":"Status","description":"New status: placed, ready, collected or cancelled. Only forward moves are allowed: placed to ready or cancelled, ready to collected or cancelled."}},"type":"object","required":["status"],"title":"OrderStatusUpdate"},"Page_BookingOut_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BookingOut"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"size":{"type":"integer","title":"Size"}},"type":"object","required":["items","total","page","size"],"title":"Page[BookingOut]"},"ResourceOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Pass this as `resource_id` where a resource is needed."},"name":{"type":"string","title":"Name"},"resource_type":{"type":"string","title":"Resource Type"},"capacity":{"type":"integer","title":"Capacity","description":"Seats or maximum party size."},"min_capacity":{"type":"integer","title":"Min Capacity"},"is_active":{"type":"boolean","title":"Is Active"},"sort_order":{"type":"integer","title":"Sort Order"},"service_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Service Ids"}},"type":"object","required":["id","name","resource_type","capacity","min_capacity","is_active","sort_order"],"title":"ResourceOut"},"ServiceOut":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Pass this as `service_id` to createBooking."},"name":{"type":"string","title":"Name"},"duration_min":{"type":"integer","title":"Duration Min","description":"Duration in minutes."},"price":{"anyOf":[{"type":"string","pattern":"^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"},{"type":"null"}],"title":"Price","description":"Price as a decimal string in the shop's currency; may be a starting price."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","name","duration_min","price","description","is_active"],"title":"ServiceOut"},"SlotOut":{"properties":{"resource_id":{"type":"string","format":"uuid","title":"Resource Id","description":"Pass this as `resource_id` to createBooking."},"resource_name":{"type":"string","title":"Resource Name"},"start_time":{"type":"string","format":"time","title":"Start Time","description":"Start, HH:MM:SS. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"end_time":{"type":"string","format":"time","title":"End Time","description":"End, HH:MM:SS. Shop-local wall-clock time in the shop's timezone (see getConnectorMe.timezone); do not convert."},"duration_min":{"type":"integer","title":"Duration Min"}},"type":"object","required":["resource_id","resource_name","start_time","end_time","duration_min"],"title":"SlotOut"},"StatsOut":{"properties":{"on_date":{"type":"string","format":"date","title":"On Date","description":"The date the numbers are for."},"total_bookings":{"type":"integer","title":"Total Bookings"},"confirmed":{"type":"integer","title":"Confirmed"},"cancelled":{"type":"integer","title":"Cancelled"},"completed":{"type":"integer","title":"Completed"},"no_show":{"type":"integer","title":"No Show"},"total_calls":{"type":"integer","title":"Total Calls"},"capacity_pct":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Capacity Pct"},"open_callbacks":{"type":"integer","title":"Open Callbacks","default":0},"total_orders":{"type":"integer","title":"Total Orders","default":0},"orders_pending":{"type":"integer","title":"Orders Pending","default":0},"orders_ready":{"type":"integer","title":"Orders Ready","default":0},"orders_collected":{"type":"integer","title":"Orders Collected","default":0},"orders_cancelled":{"type":"integer","title":"Orders Cancelled","default":0},"orders_revenue":{"type":"string","title":"Orders Revenue","default":"0.00","description":"Revenue from non-cancelled orders. Decimal string in the shop's currency."},"unmet":{"items":{"$ref":"#/components/schemas/UnmetOut"},"type":"array","title":"Unmet","default":[]}},"type":"object","required":["on_date","total_bookings","confirmed","cancelled","completed","no_show","total_calls"],"title":"StatsOut"},"UnmetOut":{"properties":{"asked":{"type":"string","title":"Asked"},"times":{"type":"integer","title":"Times"}},"type":"object","required":["asked","times"],"title":"UnmetOut"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}}}}