{"openapi":"3.0.3","info":{"title":"Slatis Public API","description":"\n# Slatis Public API\n\nThe Slatis Public API allows you to programmatically manage bookings, check availability, access team capacity data, and receive real-time notifications via webhooks.\n\n## Authentication\n\nAll API requests require authentication using an API key. Include your key in the `Authorization` header:\n\n```\nAuthorization: Bearer <your-api-key>\n```\n\nPublic keys (`pk_live_*`) are accepted on availability, event-type, and booking-create endpoints. Alternatively, pass any key in the `Slatis-Api-Key` header (legacy `X-API-Key` is still accepted).\n\n## Rate Limiting\n\nAPI requests are rate-limited per API key. Default limits:\n- **Live keys**: 1000 requests/minute\n- **Test keys**: 100 requests/minute\n\nRate limit headers are included in all authenticated responses:\n- `X-RateLimit-Limit`: Maximum requests per window\n- `X-RateLimit-Remaining`: Remaining requests in current window\n- `X-RateLimit-Reset`: Unix timestamp when the limit resets\n- `Retry-After`: Seconds until retry (only on 429 responses)\n\n## Request Headers\n\n| Header | Description |\n|--------|-------------|\n| `Authorization` | `Bearer <api-key>` |\n| `Slatis-Api-Key` | Preferred alternative to Authorization header |\n| `X-API-Key` | Legacy alternative (still accepted) |\n| `Idempotency-Key` | Prevents duplicate POST operations (max 255 chars) |\n| `Content-Type` | `application/json` for request bodies |\n\n## Response Headers\n\nAll authenticated responses include:\n- `X-Request-Id`: Unique request identifier for debugging\n- `Vary: Origin`: CORS cache hint\n\n## Request Body Limits\n\nPOST, PATCH, and PUT requests are limited to **256 KB**. Requests exceeding this limit receive a `413 Payload Too Large` response.\n\n## Idempotency\n\nFor POST requests, include an `Idempotency-Key` header to ensure the request is processed only once:\n\n```\nIdempotency-Key: unique-request-id-123\n```\n\nStatus transition endpoints (confirm, complete, no-show, cancel) are naturally idempotent — repeating the same operation returns the current state without side effects.\n\n## Errors\n\nThe API uses standard HTTP status codes and returns errors in a consistent format:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"type\": \"not_found_error\",\n    \"code\": \"not_found\",\n    \"message\": \"Booking not found\"\n  }\n}\n```\n\n| Status | Code | Description |\n|--------|------|-------------|\n| 400 | `validation_error` | Invalid request data |\n| 401 | `unauthorized` | Missing or invalid API key |\n| 403 | `forbidden` | Insufficient scope or origin not allowed |\n| 404 | `not_found` | Resource not found |\n| 409 | `conflict` | Resource conflict or invalid state transition |\n| 413 | `payload_too_large` | Request body exceeds 256 KB |\n| 429 | `rate_limit_exceeded` | Rate limit exceeded |\n| 500 | `internal_error` | Unexpected server error |\n    ","version":"1.0.0","contact":{"name":"Slatis Support","email":"support@slatis.com","url":"https://docs.slatis.com"},"license":{"name":"Proprietary","url":"https://slatis.com/legal/terms"}},"servers":[{"url":"https://api.slatis.com/v1","description":"Production"},{"url":"http://localhost:3000/api/public/v1","description":"Local Development"}],"tags":[{"name":"Bookings","description":"Create, retrieve, update, cancel, and manage booking lifecycle"},{"name":"Event Types","description":"List and retrieve event types with custom fields"},{"name":"Availability","description":"Check available time slots for event types"},{"name":"Free/Busy","description":"Query free/busy status for team members"},{"name":"Team Members","description":"List team members and check availability"},{"name":"Capacity","description":"View team capacity and workload"},{"name":"Webhooks","description":"Manage webhook endpoints for event notifications"},{"name":"Calendars","description":"List and retrieve calendar integrations for team members"}],"paths":{"/bookings":{"post":{"tags":["Bookings"],"summary":"Create a booking","description":"Create a new booking. The booking starts in DRAFT status and is processed asynchronously — a team member is assigned via routing rules and the booking transitions to SCHEDULED.","operationId":"createBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","description":"Unique key to prevent duplicate bookings from retried requests. Uniqueness is scoped per team — two teams may reuse the same key string independently. A replay returns HTTP 200 with `idempotent_replay: true` and byte-identical response body; a fresh create returns HTTP 201.","required":false,"schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBookingRequest"},"examples":{"basic":{"summary":"Basic booking","value":{"event_type_id":"evt_abc123","requested_time":"2025-01-15T10:00:00Z","attendee":{"name":"John Doe","email":"john@example.com","timezone":"America/New_York"}}},"withCustomFields":{"summary":"Booking with custom fields and metadata","value":{"event_type_id":"evt_abc123","requested_time":"2025-01-15T10:00:00Z","attendee":{"name":"Jane Smith","email":"jane@company.com","phone":"+1-555-0123","timezone":"Europe/London"},"custom_fields":{"company_size":"50-100","industry":"Technology"},"metadata":{"source":"website","campaign":"winter-promo"}}}}}}},"responses":{"200":{"description":"Idempotent replay — a booking with this Idempotency-Key (scoped to the team) already exists. The response body is byte-identical to the original 201 response with `idempotent_replay: true`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"201":{"description":"Booking created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Time slot no longer available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["Bookings"],"summary":"List bookings","description":"Retrieve a paginated list of bookings with optional filters.","operationId":"listBookings","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"status","in":"query","description":"Filter by booking status","schema":{"type":"string","enum":["DRAFT","SCHEDULED","PENDING_CONFIRMATION","RESCHEDULED","CANCELLED","COMPLETED","NO_SHOW"]}},{"name":"event_type_id","in":"query","description":"Filter by event type ID","schema":{"type":"string"}},{"name":"assigned_to_id","in":"query","description":"Filter by assigned team member ID","schema":{"type":"string"}},{"name":"attendee_email","in":"query","description":"Filter by attendee email","schema":{"type":"string","format":"email"}},{"name":"start_date","in":"query","description":"Filter bookings starting after this date (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"end_date","in":"query","description":"Filter bookings starting before this date (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","description":"Number of results per page (max 100)","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","description":"Opaque cursor from previous response `pagination.next_cursor` for next page","schema":{"type":"string"}}],"responses":{"200":{"description":"List of bookings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/{id}":{"get":{"tags":["Bookings"],"summary":"Get a booking","description":"Retrieve a single booking by ID with full details including custom fields.","operationId":"getBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Booking details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Bookings"],"summary":"Update booking attendee","description":"Update attendee details (name, email, phone, timezone) on an existing booking. Only attendee fields are accepted — scheduling fields (start_time, status, event_type_id, team_id, api_key_id) must be changed via reschedule/reassign/status endpoints and will be rejected here. Allowed only while the booking is in SCHEDULED, RESCHEDULED, or PENDING_CONFIRMATION state. On success a `BOOKING_UPDATED` webhook is broadcast to every active subscription in the organization, the external calendar event attendees are patched, and booking caches are invalidated. If the attendee email changes, a fresh confirmation email is sent to the new address.","operationId":"updateBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBookingRequest"},"examples":{"changeEmail":{"summary":"Change attendee email","value":{"attendee":{"email":"new@example.com"}}},"renameAndPhone":{"summary":"Rename and set phone","value":{"attendee":{"name":"Jane Doe","phone":"+15555550123"}}}}}}},"responses":{"200":{"description":"Booking updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"400":{"description":"No fields to update, disallowed field present, or invalid data (e.g. bad email format)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Booking was modified concurrently. Refresh and retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Booking is in a terminal state (CANCELLED, COMPLETED, NO_SHOW) and cannot be updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Bookings"],"summary":"Cancel a booking","description":"Cancel a booking. Returns 422 if the organization has disabled cancellations or the cancellation cutoff window has passed. Returns 409 on concurrent modification — retry with the latest booking state.","operationId":"cancelBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Cancellation reason","maxLength":500}}}}}},"responses":{"200":{"description":"Booking successfully cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Booking was modified concurrently or is already cancelled. Refresh and retry.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Cancellation blocked by policy: organization has disabled cancellations, the cancellation cutoff window has passed, or the booking is in a terminal state (COMPLETED, NO_SHOW).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/{id}/reschedule":{"post":{"tags":["Bookings"],"summary":"Reschedule a booking","description":"Change the date/time of an existing booking. Triggers side effects (email, calendar update).","operationId":"rescheduleBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["start_time"],"properties":{"start_time":{"type":"string","format":"date-time","description":"New start time (ISO 8601)"},"reason":{"type":"string","description":"Reason for rescheduling","maxLength":500}}}}}},"responses":{"200":{"description":"Booking rescheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Time slot not available or invalid status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/{id}/confirm":{"post":{"tags":["Bookings"],"summary":"Confirm a booking","description":"Confirm a PENDING_CONFIRMATION booking, transitioning it to SCHEDULED. Naturally idempotent.","operationId":"confirmBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Booking confirmed (or already confirmed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Booking status does not allow confirmation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/{id}/complete":{"post":{"tags":["Bookings"],"summary":"Complete a booking","description":"Mark a SCHEDULED or RESCHEDULED booking as COMPLETED. Naturally idempotent.","operationId":"completeBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Booking completed (or already completed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Booking status does not allow completion","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/{id}/no-show":{"post":{"tags":["Bookings"],"summary":"Mark booking as no-show","description":"Mark a SCHEDULED or RESCHEDULED booking as NO_SHOW. Naturally idempotent.","operationId":"noShowBooking","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Booking ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Booking marked as no-show (or already no-show)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Booking status does not allow no-show","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/bookings/external/{externalId}":{"get":{"tags":["Bookings"],"summary":"Get booking by external ID","description":"Look up a booking by its external ID. Useful for correlating bookings with external systems.","operationId":"getBookingByExternalId","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"externalId","in":"path","required":true,"description":"External ID assigned to the booking","schema":{"type":"string"}}],"responses":{"200":{"description":"Booking details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Booking not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/event-types":{"get":{"tags":["Event Types"],"summary":"List event types","description":"Get all active event types for your organization.","operationId":"listEventTypes","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"List of event types","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event_types":{"type":"array","items":{"$ref":"#/components/schemas/EventType"}}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Event Types"],"summary":"Create an event type","description":"Create a new event type. Requires scope `event-types:write` (secret key only). The owning team must belong to the caller’s organization; if `is_personal` is true, `owner_id` is required.","operationId":"createEventType","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventTypeRequest"}}}},"responses":{"201":{"description":"Event type created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event_type":{"$ref":"#/components/schemas/EventType"}}}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key missing required scope or team outside organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Slug or external_id conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/event-types/{id}":{"get":{"tags":["Event Types"],"summary":"Get an event type","description":"Retrieve a single event type by ID with full details including custom fields.","operationId":"getEventType","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Event type details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event_type":{"$ref":"#/components/schemas/EventTypeDetail"}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Event type not found, inactive, deleted, or outside the API key organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Event Types"],"summary":"Update an event type","description":"Update an event type owned by your organization. Requires scope `event-types:write` (secret key only). All fields are optional; only provided fields are changed. A `warning` string is returned when a duration change affects future bookings (those keep their original duration).","operationId":"updateEventType","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventTypeRequest"}}}},"responses":{"200":{"description":"Event type updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event_type":{"$ref":"#/components/schemas/EventType"},"warning":{"type":"string","nullable":true}}}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key missing required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Event type not found, deleted, or outside the API key organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Slug conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Event Types"],"summary":"Delete an event type","description":"Soft-delete an event type. Requires scope `event-types:write` (secret key only). Blocked with 422 `precondition_failed` if the event type has active (SCHEDULED) bookings; cancel or complete those first.","operationId":"deleteEventType","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Event type soft-deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event_type":{"type":"object","properties":{"id":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key missing required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Event type not found, deleted, or outside the API key organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Event type has active bookings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/event-types/{id}/fields":{"get":{"tags":["Event Types"],"summary":"Get event type fields","description":"Retrieve custom fields and standard fields for a specific event type. Useful for building dynamic booking forms.","operationId":"getEventTypeFields","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Event type fields with validation rules","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventTypeFieldsResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Event type not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/availability":{"get":{"tags":["Availability"],"summary":"Get available slots","description":"Get available time slots for a specific event type and date range.","operationId":"getAvailability","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"event_type_id","in":"query","required":true,"description":"Event type ID","schema":{"type":"string"}},{"name":"start_date","in":"query","required":true,"description":"Start of date range (ISO 8601)","schema":{"type":"string","format":"date"}},{"name":"end_date","in":"query","required":true,"description":"End of date range (ISO 8601)","schema":{"type":"string","format":"date"}},{"name":"timezone","in":"query","description":"Timezone for slots (IANA format)","schema":{"type":"string","default":"UTC"}}],"responses":{"200":{"description":"Available time slots","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailabilityResponse"}}}}}}},"/freebusy/{userId}":{"get":{"tags":["Free/Busy"],"summary":"Get free/busy slots","description":"Query the free/busy schedule for a specific user over a date range. Returns time slots with free or busy status based on working hours, existing bookings, and out-of-office entries. Response is cached for 60 seconds.","operationId":"getFreeBusy","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"description":"User ID (UUID format)","schema":{"type":"string","format":"uuid"}},{"name":"start","in":"query","required":true,"description":"Start of date range (ISO 8601)","schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","required":true,"description":"End of date range (ISO 8601). Maximum 30 days from start.","schema":{"type":"string","format":"date-time"}},{"name":"time_slot","in":"query","description":"Slot duration in minutes (15-120, default 30)","schema":{"type":"integer","minimum":15,"maximum":120,"default":30}}],"responses":{"200":{"description":"Free/busy slots for the user","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}},"Cache-Control":{"description":"Response is cacheable for 60 seconds","schema":{"type":"string","example":"public, max-age=60"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FreeBusyResponse"}}}},"400":{"description":"Invalid date range, format, or time slot","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User not found or has no active calendar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/team/members":{"get":{"tags":["Team Members"],"summary":"List team members","description":"List team members in your organization with optional filters. Results are paginated.","operationId":"listTeamMembers","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"team_id","in":"query","description":"Filter by team ID","schema":{"type":"string"}},{"name":"skills","in":"query","description":"Comma-separated list of skills to filter by (OR match)","schema":{"type":"string"}},{"name":"is_active","in":"query","description":"Filter by active status","schema":{"type":"boolean"}},{"name":"limit","in":"query","description":"Number of results per page (max 100)","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","description":"Number of results to skip","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Paginated list of team members","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/team/members/available":{"get":{"tags":["Team Members"],"summary":"List available team members","description":"List active team members with availability information for a specific date. Includes booking counts, capacity limits, and next available slot when fully booked.","operationId":"listAvailableTeamMembers","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"date","in":"query","required":true,"description":"Date to check availability (YYYY-MM-DD)","schema":{"type":"string","format":"date"}},{"name":"duration","in":"query","description":"Booking duration in minutes (default 30)","schema":{"type":"integer","default":30}},{"name":"team_id","in":"query","description":"Filter by team ID","schema":{"type":"string"}},{"name":"skills","in":"query","description":"Comma-separated list of skills to filter by (OR match)","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Results per page (1–100, default 50)","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","description":"Pagination offset","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"List of team members with availability","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberAvailable"}},"date":{"type":"string","format":"date"},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid date format or parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/team/members/{id}":{"get":{"tags":["Team Members"],"summary":"Get a team member","description":"Get details of a specific team member by ID.","operationId":"getTeamMember","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Team member ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Team member details","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"member":{"$ref":"#/components/schemas/TeamMember"}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Team member not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/capacity":{"get":{"tags":["Capacity"],"summary":"Get team capacity","description":"Get current team capacity and workload information.","operationId":"getCapacity","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"team_id","in":"query","description":"Filter by team ID","schema":{"type":"string"}},{"name":"member_id","in":"query","description":"Filter by member ID","schema":{"type":"string"}},{"name":"start_date","in":"query","description":"Start of date range (ISO 8601 datetime). Defaults to now.","schema":{"type":"string","format":"date-time"}},{"name":"end_date","in":"query","description":"End of date range (ISO 8601 datetime). Defaults to 7 days from now.","schema":{"type":"string","format":"date-time"}},{"name":"group_by","in":"query","description":"Timeline grouping","schema":{"type":"string","enum":["day","week","month"],"default":"day"}}],"responses":{"200":{"description":"Team capacity data","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CapacityResponse"}}}}}}},"/calendars":{"get":{"tags":["Calendars"],"summary":"List calendar integrations","description":"List calendar integrations connected by members of your organization. Requires scope `calendars:read` (secret key only). OAuth tokens, provider account IDs, sync tokens, webhook state, and sync metadata are never exposed.","operationId":"listCalendarIntegrations","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"user_id","in":"query","required":false,"description":"Filter by user ID","schema":{"type":"string","format":"uuid"}},{"name":"team_id","in":"query","required":false,"description":"Filter by team ID","schema":{"type":"string"}},{"name":"provider","in":"query","required":false,"schema":{"type":"string","enum":["GOOGLE","MICROSOFT","APPLE"]}},{"name":"sync_status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","SYNCING","SUCCESS","ERROR","NEEDS_REAUTH"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"List of calendar integrations","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarIntegrationListResponse"}}}},"400":{"description":"Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key missing required scope (calendars:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/calendars/{userId}":{"get":{"tags":["Calendars"],"summary":"List a user’s calendar integrations","description":"List calendar integrations for a specific user in your organization. Requires scope `calendars:read` (secret key only). Returns 404 if the user does not belong to the calling key’s organization.","operationId":"listUserCalendarIntegrations","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"description":"User ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Calendar integrations for the user","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarIntegrationUserListResponse"}}}},"401":{"description":"Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"API key missing required scope (calendars:read)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User not found in the calling key’s organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks":{"post":{"tags":["Webhooks"],"summary":"Create a webhook","description":"Register a new webhook endpoint to receive event notifications. The secret is returned only in the creation response — store it securely.\n\n**Delivery guarantees.** Each event is delivered with HMAC-SHA256 signatures (header `X-Slatis-Signature`). Failed deliveries are retried with exponential backoff across 5 attempts (≈1s, 5s, 25s, 125s, 625s); responses in the 2xx range are treated as success. After 10 consecutive delivery failures the webhook is automatically disabled (`is_active` flips to `false`) and the most recent `failure_reason` is exposed on `GET /webhooks/{id}`. Re-enable by patching `is_active: true` once the target endpoint is healthy.","operationId":"createWebhook","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook created (includes secret — only shown once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreatedResponse"}}}},"400":{"description":"Invalid request data. Error codes: `validation_error` (schema/URL format/event enum), `invalid_url` (URL resolved to a private/loopback/metadata address, or hostname DNS lookup failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A webhook with this URL already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["Webhooks"],"summary":"List webhooks","description":"Get all registered webhooks for your organization, with aggregated delivery stats. Requires scope `webhooks:read` or `webhooks:manage`.","operationId":"listWebhooks","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"is_active","in":"query","description":"Filter by active status","schema":{"type":"boolean"}}],"responses":{"200":{"description":"List of webhooks with delivery stats","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookListItem"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}":{"get":{"tags":["Webhooks"],"summary":"Get a webhook","description":"Get details of a specific webhook including delivery stats and recent deliveries. Requires scope `webhooks:read` or `webhooks:manage`.","operationId":"getWebhook","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook details with delivery history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Webhooks"],"summary":"Update a webhook","description":"Update webhook configuration (URL, events, description, active status).","operationId":"updateWebhook","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookRequest"}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"400":{"description":"Invalid request data. Error codes: `validation_error` (schema/URL format/event enum), `invalid_url` (URL resolved to a private/loopback/metadata address, or hostname DNS lookup failed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A webhook with this URL already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Webhooks"],"summary":"Delete a webhook","description":"Soft-delete a webhook endpoint. Returns the full deleted webhook record; `deleted_at` indicates when it was removed.","operationId":"deleteWebhook","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"webhook":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"deleted_at":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/test":{"post":{"tags":["Webhooks"],"summary":"Test a webhook","description":"Send a test BOOKING_CREATED event to the webhook endpoint. The delivery is recorded in webhook_deliveries. The raw response body from the target endpoint is never returned to the caller. Rate-limited to 1 request per minute per webhook.","operationId":"testWebhook","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Webhook URL is not allowed (points to a private, loopback, or metadata address)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/rotate-secret":{"post":{"tags":["Webhooks"],"summary":"Rotate a webhook secret","description":"Generate a new HMAC signing secret for the webhook, replacing the current one. The plaintext secret is returned once in the response — store it securely. All deliveries after rotation are signed with the new secret; signatures from the previous secret will stop validating immediately.","operationId":"rotateWebhookSecret","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Secret rotated (plaintext returned once)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"webhook":{"type":"object","properties":{"id":{"type":"string"},"secret":{"type":"string","description":"New plaintext secret — shown only once"},"rotated_at":{"type":"string","format":"date-time"}}}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/webhooks/{id}/deliveries":{"get":{"tags":["Webhooks"],"summary":"List webhook deliveries","description":"Get a paginated list of delivery attempts for a specific webhook. Filter by success status or event type. Requires scope `webhooks:read` or `webhooks:manage`.","operationId":"listWebhookDeliveries","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Webhook ID","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Number of results per page (max 100)","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","description":"Number of results to skip","schema":{"type":"integer","minimum":0,"default":0}},{"name":"success","in":"query","description":"Filter by delivery success status","schema":{"type":"boolean"}},{"name":"event_type","in":"query","description":"Filter by webhook event type","schema":{"$ref":"#/components/schemas/WebhookEvent"}}],"responses":{"200":{"description":"Paginated list of webhook deliveries","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"event_type":{"type":"string"},"status_code":{"type":"integer","nullable":true},"success":{"type":"boolean"},"error_message":{"type":"string","nullable":true},"delivery_duration":{"type":"integer","nullable":true,"description":"Duration in ms"},"attempt":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"has_more":{"type":"boolean"}}}}}}}},"401":{"description":"Invalid or missing API key","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"Request body exceeds 256 KB","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/monitor/availability":{"get":{"tags":["Monitor"],"summary":"Synthetic availability probe","description":"Runs a real availability check against a configured event type and returns slot count. Designed for uptime monitoring integrations (e.g. BetterStack, UptimeRobot). Requires an API key with `availability:read` scope.","operationId":"monitorAvailability","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Probe succeeded — availability engine is healthy","headers":{"X-Request-Id":{"description":"Unique request identifier (UUID v4 by default). Echoed back when the client supplies a valid `X-Request-Id` request header. Use this value to correlate requests with server logs.","schema":{"type":"string","maxLength":128}},"Vary":{"description":"Vary: Origin — CORS cache hint.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","monitor","probedEventTypeId","probedDate","totalSlots"],"properties":{"success":{"type":"boolean","example":true},"monitor":{"type":"string","example":"availability"},"probedEventTypeId":{"type":"string"},"probedDate":{"type":"string","format":"date","example":"2026-04-23"},"totalSlots":{"type":"integer","example":8}}}}}},"503":{"description":"Probe misconfigured — MONITOR_EVENT_TYPE_ID not set or not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"http","scheme":"bearer","description":"Use a secret key (sk_live_*) for server-to-server requests, or a public key (pk_live_*) for client-side flows. Alternatively pass the key in the Slatis-Api-Key header (or legacy X-API-Key). Get your keys from Settings → API Keys."}},"schemas":{"CreateBookingRequest":{"type":"object","required":["event_type_id","requested_time","attendee"],"properties":{"event_type_id":{"type":"string","description":"ID of the event type to book"},"requested_time":{"type":"string","format":"date-time","description":"Requested start time in ISO 8601 format"},"attendee":{"type":"object","required":["name","email"],"properties":{"name":{"type":"string","minLength":1},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"timezone":{"type":"string","description":"IANA timezone"}}},"custom_fields":{"type":"object","additionalProperties":true,"description":"Custom field values keyed by field key"},"form_responses":{"type":"object","additionalProperties":true,"description":"Form response data keyed by field key"},"metadata":{"type":"object","additionalProperties":{"type":"string"},"description":"Arbitrary string metadata to store with the booking"},"assign_to":{"type":"string","description":"Team member ID to assign to (overrides routing)"},"idempotency_key":{"type":"string","description":"Idempotency key (alternative to Idempotency-Key header)"}}},"UpdateBookingRequest":{"type":"object","required":["attendee"],"additionalProperties":false,"properties":{"attendee":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"name":{"type":"string","minLength":1},"email":{"type":"string","format":"email"},"phone":{"type":"string","nullable":true},"timezone":{"type":"string","nullable":true,"description":"IANA timezone"}}}}},"Booking":{"type":"object","properties":{"object":{"type":"string","enum":["booking"]},"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string","enum":["DRAFT","SCHEDULED","PENDING_CONFIRMATION","RESCHEDULED","CANCELLED","COMPLETED","NO_SHOW"]},"start_time":{"type":"string","format":"date-time"},"end_time":{"type":"string","format":"date-time"},"duration":{"type":"integer","description":"Duration in minutes"},"attendee":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string","nullable":true},"timezone":{"type":"string","nullable":true}}},"event_type":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"assigned_to":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}}},"video_link":{"type":"string","nullable":true},"video_provider":{"type":"string","nullable":true,"enum":["google_meet","zoom","teams"]},"video_meeting_id":{"type":"string","nullable":true},"location":{"type":"string","nullable":true},"custom_fields":{"type":"object","additionalProperties":true},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"routing_model":{"type":"string","nullable":true,"description":"Routing model configured on the event type at the time of booking. One of: rotation, weighted, match, balance, reserved, manual. Null when unavailable (e.g. POST /bookings response before worker processes the booking).","enum":["rotation","weighted","match","balance","reserved","manual"]},"assignment_reason":{"type":"object","nullable":true,"description":"Summary of the latest routing decision for this booking. Only populated on GET /v1/bookings/{id} and state-transition responses (confirm, complete, no-show). Null on list responses and immediately after creation.","properties":{"reason_type":{"type":"string","description":"Categorised reason for the assignment decision.","enum":["CAPACITY_BEST_MATCH","CAPACITY_ONLY_AVAILABLE","FAIRNESS_LOWEST_UTILIZATION","OVERALLOCATION_FORCED","MANUAL_ADMIN_CHOICE","SKILL_MATCH_REQUIRED","SIMPLE_ROUND_ROBIN","PERSONAL_DIRECT"]},"outcome":{"type":"string","nullable":true,"description":"Booking outcome captured after terminal status transition. Populated on COMPLETED, NO_SHOW, and CANCELLED bookings. Null for bookings that have not reached a terminal state."},"model":{"type":"string","nullable":true,"description":"Routing model that produced this assignment decision."}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"BookingResponse":{"type":"object","properties":{"success":{"type":"boolean"},"booking":{"$ref":"#/components/schemas/Booking"},"idempotent_replay":{"type":"boolean","description":"Present on POST /bookings responses. `true` when the request matched an existing Idempotency-Key and the booking was not re-created (HTTP 200). `false` when a new booking was created (HTTP 201)."}}},"BookingListResponse":{"type":"object","properties":{"success":{"type":"boolean"},"bookings":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}},"pagination":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}}}}},"EventType":{"type":"object","properties":{"object":{"type":"string","enum":["event_type"]},"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string","nullable":true},"duration":{"type":"integer","description":"Duration in minutes"},"slot_interval":{"type":"integer","nullable":true,"description":"Slot interval in minutes"},"buffer_before":{"type":"integer","description":"Buffer before event in minutes"},"buffer_after":{"type":"integer","description":"Buffer after event in minutes"},"minimum_booking_notice":{"type":"integer","description":"Minimum booking notice in minutes"},"scheduling_type":{"type":"string","nullable":true,"enum":["SOLO","ROUND_ROBIN","COLLECTIVE",null]},"routing_model":{"type":"string","nullable":true,"enum":["rotation","weighted","match","balance","reserved","manual"],"description":"Routing model for assignment"},"color":{"type":"string","nullable":true,"enum":["blue","green","orange","purple","red","sky","gray","amber","slate"]},"external_id":{"type":"string","nullable":true},"external_source":{"type":"string","nullable":true,"enum":["calcom","calendly"]},"is_personal":{"type":"boolean"},"is_active":{"type":"boolean"},"owner_id":{"type":"string","nullable":true},"timezone":{"type":"string","nullable":true,"description":"IANA timezone"},"form_schema":{"type":"object","nullable":true,"additionalProperties":true},"team_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"EventTypeWorkload":{"type":"object","required":["prep","meeting","implementation","admin"],"properties":{"prep":{"type":"integer","minimum":0},"meeting":{"type":"integer","minimum":1},"implementation":{"type":"integer","minimum":0},"admin":{"type":"integer","minimum":0}}},"EventTypeLocation":{"type":"object","required":["type"],"properties":{"type":{"type":"string","minLength":1},"label":{"type":"string"},"default_value":{"type":"string"},"display_publicly":{"type":"boolean"},"credential_id":{"type":"string","format":"uuid","nullable":true}}},"CreateEventTypeRequest":{"type":"object","required":["team_id","name","duration","workload"],"properties":{"team_id":{"type":"string","minLength":1},"name":{"type":"string","minLength":1,"maxLength":100},"slug":{"type":"string","minLength":3,"maxLength":60,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"},"description":{"type":"string","maxLength":500},"duration":{"type":"integer","minimum":1},"routing_model":{"type":"string","enum":["rotation","weighted","match","balance","reserved","manual"]},"color":{"type":"string","enum":["blue","green","orange","purple","red","sky","gray","amber","slate"]},"external_id":{"type":"string"},"external_source":{"type":"string","enum":["calcom","calendly"]},"workload":{"$ref":"#/components/schemas/EventTypeWorkload"},"locations":{"type":"array","items":{"$ref":"#/components/schemas/EventTypeLocation"}},"is_personal":{"type":"boolean","default":false},"owner_id":{"type":"string","format":"uuid","description":"Required when `is_personal` is true"},"assignment_pool_id":{"type":"string","nullable":true},"primary_calendar_id":{"type":"string","format":"uuid","nullable":true},"booking_limits":{"type":"object","nullable":true,"additionalProperties":true},"timezone":{"type":"string","nullable":true,"description":"IANA timezone"}}},"UpdateEventTypeRequest":{"type":"object","description":"All fields optional; only provided fields are updated.","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"slug":{"type":"string","minLength":3,"maxLength":60,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$"},"description":{"type":"string","maxLength":500,"nullable":true},"duration":{"type":"integer","minimum":1},"routing_model":{"type":"string","enum":["rotation","weighted","match","balance","reserved","manual"]},"color":{"type":"string","nullable":true,"enum":["blue","green","orange","purple","red","sky","gray","amber","slate"]},"is_active":{"type":"boolean"},"workload":{"$ref":"#/components/schemas/EventTypeWorkload"},"locations":{"type":"array","items":{"$ref":"#/components/schemas/EventTypeLocation"}},"is_personal":{"type":"boolean"},"owner_id":{"type":"string","format":"uuid","nullable":true},"assignment_pool_id":{"type":"string","nullable":true},"primary_calendar_id":{"type":"string","format":"uuid","nullable":true},"booking_limits":{"type":"object","nullable":true,"additionalProperties":true},"timezone":{"type":"string","nullable":true}}},"EventTypeDetail":{"type":"object","description":"Full event type with custom fields (returned by GET /event-types/{id})","properties":{"object":{"type":"string","enum":["event_type"]},"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string","nullable":true},"duration":{"type":"integer"},"slot_interval":{"type":"integer","nullable":true},"buffer_before":{"type":"integer"},"buffer_after":{"type":"integer"},"minimum_booking_notice":{"type":"integer"},"scheduling_type":{"type":"string","nullable":true},"routing_model":{"type":"string","nullable":true,"enum":["rotation","weighted","match","balance","reserved","manual"],"description":"Routing model for assignment"},"form_schema":{"type":"object","nullable":true,"additionalProperties":true},"is_active":{"type":"boolean"},"is_personal":{"type":"boolean"},"team_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"custom_fields":{"type":"array","items":{"$ref":"#/components/schemas/CustomField"}}}},"CustomField":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string","enum":["TEXT","LONG_TEXT","NUMBER","SELECT","MULTI_SELECT","DATE","DATETIME","CHECKBOX","EMAIL","PHONE","URL"]},"required":{"type":"boolean"},"options":{"type":"array","items":{"type":"string"}},"placeholder":{"type":"string","nullable":true},"order":{"type":"integer"}}},"EventTypeFieldsResponse":{"type":"object","properties":{"success":{"type":"boolean"},"event_type":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"description":{"type":"string","nullable":true},"duration":{"type":"integer"}}},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"required":{"type":"boolean"},"options":{"type":"array","items":{"type":"string"}},"placeholder":{"type":"string","nullable":true},"help_text":{"type":"string","nullable":true},"default_value":{"type":"string","nullable":true},"validation":{"type":"object","properties":{"pattern":{"type":"string","nullable":true},"min_value":{"type":"number","nullable":true},"max_value":{"type":"number","nullable":true}}},"order":{"type":"integer"}}}},"standard_fields":{"type":"object","properties":{"name":{"type":"object","properties":{"required":{"type":"boolean"},"label":{"type":"string"}}},"email":{"type":"object","properties":{"required":{"type":"boolean"},"label":{"type":"string"}}},"phone":{"type":"object","properties":{"required":{"type":"boolean"},"label":{"type":"string"}}},"notes":{"type":"object","properties":{"required":{"type":"boolean"},"label":{"type":"string"}}}}}}},"TeamMember":{"type":"object","properties":{"object":{"type":"string","enum":["team_member"]},"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"role":{"type":"string"},"skills":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"team":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}},"TeamMemberAvailable":{"type":"object","description":"Team member with availability info for a specific date","properties":{"object":{"type":"string","enum":["team_member"]},"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"role":{"type":"string"},"skills":{"type":"array","items":{"type":"string"}},"is_active":{"type":"boolean"},"team":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"availability":{"type":"object","properties":{"is_available":{"type":"boolean"},"next_available_slot":{"type":"string","nullable":true,"format":"date"},"booked_slots":{"type":"integer"},"max_bookings_per_day":{"type":"integer"}}}}},"FreeBusySlot":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["free","busy"]}}},"FreeBusyResponse":{"type":"object","properties":{"success":{"type":"boolean"},"user_id":{"type":"string"},"query":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"time_slot_minutes":{"type":"integer"}}},"timezone":{"type":"string"},"working_hours":{"type":"array","description":"Per-day working hours from the user schedule, sorted by day_of_week","items":{"type":"object","properties":{"day_of_week":{"type":"integer","description":"0=Sunday, 1=Monday, ..., 6=Saturday"},"windows":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","description":"HH:mm format"},"end":{"type":"string","description":"HH:mm format"}}}}}}},"slots":{"type":"array","items":{"$ref":"#/components/schemas/FreeBusySlot"}}}},"AvailabilityResponse":{"type":"object","properties":{"success":{"type":"boolean"},"slots":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}}}}},"CapacityResponse":{"type":"object","properties":{"success":{"type":"boolean"},"capacity":{"type":"object","properties":{"overview":{"type":"object","properties":{"total_members":{"type":"integer"},"active_members":{"type":"integer"},"average_utilization":{"type":"number"},"total_bookings":{"type":"integer"},"available_slots":{"type":"integer"}}},"members":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","enum":["team_member"]},"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string"},"avatar_url":{"type":"string","nullable":true},"capacity":{"type":"object","properties":{"max_bookings_per_day":{"type":"integer"},"max_bookings_in_range":{"type":"integer"},"current_bookings":{"type":"integer"},"utilization":{"type":"number"},"available_slots":{"type":"integer"}}},"workload":{"type":"object","properties":{"total_hours":{"type":"number"},"booked_hours":{"type":"number"},"available_hours":{"type":"number"}}},"bookings_by_status":{"type":"object","properties":{"scheduled":{"type":"integer"},"completed":{"type":"integer"},"cancelled":{"type":"integer"},"no_show":{"type":"integer"},"rescheduled":{"type":"integer"}}}}}},"timeline":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"total_bookings":{"type":"integer"},"scheduled_bookings":{"type":"integer"},"utilization":{"type":"number"},"available_slots":{"type":"integer"}}}}}},"date_range":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"group_by":{"type":"string","enum":["day","week","month"]}}}}},"CalendarIntegration":{"type":"object","description":"Calendar integration metadata. Sensitive fields (access/refresh tokens, provider account IDs, sync tokens, delta links, webhook client state, metadata) are never exposed.","properties":{"object":{"type":"string","enum":["calendar_integration"]},"id":{"type":"string"},"user_id":{"type":"string"},"team_id":{"type":"string","nullable":true},"provider":{"type":"string","enum":["GOOGLE","MICROSOFT","APPLE"]},"calendar_id":{"type":"string","description":"Provider-side calendar identifier (e.g. Google calendarId)"},"calendar_name":{"type":"string","nullable":true},"provider_email":{"type":"string","nullable":true},"timezone":{"type":"string"},"is_primary":{"type":"boolean"},"sync_status":{"type":"string","enum":["PENDING","SYNCING","SUCCESS","ERROR","NEEDS_REAUTH"]},"last_sync_at":{"type":"string","format":"date-time","nullable":true},"supports_webhooks":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"CalendarIntegrationListResponse":{"type":"object","properties":{"success":{"type":"boolean"},"calendars":{"type":"array","items":{"$ref":"#/components/schemas/CalendarIntegration"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"has_more":{"type":"boolean"}}}}},"CalendarIntegrationUserListResponse":{"type":"object","properties":{"success":{"type":"boolean"},"user_id":{"type":"string","format":"uuid"},"calendars":{"type":"array","items":{"$ref":"#/components/schemas/CalendarIntegration"}}}},"ApiKeyScope":{"type":"string","enum":["bookings:create","bookings:read","bookings:read-own","bookings:update","bookings:cancel","bookings:reschedule","bookings:transition","bookings:write","event-types:read","event-types:write","availability:read","team:read","calendars:read","webhooks:read","webhooks:manage","analytics:read"],"description":"Permission scope. Public keys (pk_*) may only use: bookings:create, bookings:read-own, event-types:read, availability:read, team:read. The `bookings:write` scope is a grouping alias that grants all five booking-write scopes (create, update, cancel, reschedule, transition); routes remain documented with their fine-grained scope."},"WebhookEvent":{"type":"string","enum":["BOOKING_CREATED","BOOKING_UPDATED","BOOKING_CANCELLED","BOOKING_RESCHEDULED","BOOKING_COMPLETED","BOOKING_NO_SHOW","ASSIGNMENT_CHANGED"]},"CreateWebhookRequest":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"Publicly reachable HTTPS URL (port 443 or 8443). Private/loopback/link-local/metadata IPs and internal-suffix hostnames are rejected."},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1},"secret":{"type":"string","minLength":16,"description":"HMAC secret for signature verification. Auto-generated if omitted."},"description":{"type":"string","maxLength":500},"is_active":{"type":"boolean","default":true}}},"UpdateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Publicly reachable HTTPS URL (port 443 or 8443). Private/loopback/link-local/metadata IPs and internal-suffix hostnames are rejected."},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEvent"},"minItems":1},"description":{"type":"string","maxLength":500},"is_active":{"type":"boolean"}}},"Webhook":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"description":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"consecutive_failures":{"type":"integer"},"delivery_stats":{"type":"object","properties":{"total_deliveries":{"type":"integer"},"successful_deliveries":{"type":"integer"},"failed_deliveries":{"type":"integer"},"success_rate":{"type":"number"},"avg_delivery_duration":{"type":"integer","description":"Average duration in ms"},"last_delivery_at":{"type":"string","format":"date-time","nullable":true},"last_delivery_success":{"type":"boolean","nullable":true}}},"recent_deliveries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"event_type":{"type":"string"},"status_code":{"type":"integer","nullable":true},"success":{"type":"boolean"},"error_message":{"type":"string","nullable":true},"delivery_duration":{"type":"integer","nullable":true},"attempt":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookListItem":{"type":"object","description":"Webhook in list response (no recent_deliveries)","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"description":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"consecutive_failures":{"type":"integer"},"delivery_stats":{"type":"object","properties":{"total_deliveries":{"type":"integer"},"successful_deliveries":{"type":"integer"},"success_rate":{"type":"number"},"last_delivery_at":{"type":"string","format":"date-time","nullable":true},"last_delivery_success":{"type":"boolean","nullable":true}}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"WebhookResponse":{"type":"object","properties":{"success":{"type":"boolean"},"webhook":{"$ref":"#/components/schemas/Webhook"}}},"WebhookCreatedResponse":{"type":"object","description":"Create response includes the secret (only shown once)","properties":{"success":{"type":"boolean"},"webhook":{"type":"object","properties":{"object":{"type":"string","enum":["webhook"]},"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"secret":{"type":"string","description":"HMAC secret — only returned on creation"},"description":{"type":"string","nullable":true},"is_active":{"type":"boolean"},"consecutive_failures":{"type":"integer"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}}}},"WebhookTestResponse":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"delivery":{"type":"object","properties":{"success":{"type":"boolean"},"status_code":{"type":"integer","nullable":true},"error_message":{"type":"string","nullable":true},"duration":{"type":"integer","description":"Duration in ms"},"timestamp":{"type":"string","format":"date-time"}}}}},"AssignmentChangedPayload":{"type":"object","description":"Payload for the ASSIGNMENT_CHANGED webhook event. Fired when a booking is reassigned to a different team member. Fields use camelCase consistent with all Slatis webhook payloads.","required":["bookingId","previousAssignedToId","newAssignedToId","reason","initiatedBy","videoLink","videoProvider"],"properties":{"bookingId":{"type":"string","description":"ID of the reassigned booking."},"previousAssignedToId":{"type":"string","nullable":true,"description":"Team member ID of the previous assignee, or null if the booking was unassigned."},"newAssignedToId":{"type":"string","nullable":true,"description":"Team member ID of the new assignee."},"reason":{"type":"string","nullable":true,"description":"Reassignment reason provided by the operator."},"initiatedBy":{"type":"string","description":"User ID of the actor who performed the reassignment."},"videoLink":{"type":"string","nullable":true,"description":"Conference URL for the new assignee's meeting. Null if the event type uses a non-video location (phone, in-person), or if conference creation failed after reassign (admin is notified separately in that case)."},"videoProvider":{"type":"string","nullable":true,"enum":["google_meet","teams","zoom"],"description":"Video conferencing provider for the new assignee. Null when videoLink is null. Reflects the new assignee's provider — may differ from the previous assignee's provider on cross-provider reassign."}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"type":{"type":"string","description":"Coarse-grained error category for programmatic handling","enum":["invalid_request_error","authentication_error","permission_error","not_found_error","rate_limit_error","server_error"]},"code":{"type":"string","description":"Fine-grained machine-readable error code","enum":["validation_error","unauthorized","forbidden","not_found","conflict","rate_limited","payload_too_large","internal_error","precondition_failed","invalid_url","webhook_url_not_allowed","external_service_error"]},"message":{"type":"string","description":"Human-readable error message"}}}}}}}}