{"openapi":"3.1.0","info":{"title":"OpenReserve API for agents","version":"3.2.0","description":"Operations an agent key may call. Read https://api.openreserve.app/v1/agent/guide first."},"servers":[{"url":"https://api.openreserve.app"}],"tags":[{"name":"meta"},{"name":"public"},{"name":"tenants"},{"name":"members"},{"name":"audit"},{"name":"media"},{"name":"domains"},{"name":"agent"},{"name":"billing"},{"name":"payments"},{"name":"notes"},{"name":"booking"}],"paths":{"/v1/health":{"get":{"operationId":"meta.health","summary":"Check that the API is up","tags":["meta"],"security":[],"responses":{"200":{"description":"Check that the API is up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To check that the API is reachable and which contract version it serves."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/app-config":{"get":{"operationId":"meta.appConfig","summary":"Get client configuration (versions, features, sign-in client ids)","description":"Apps call this at start-up. `appId` selects a mobile app (brand.json `mobile.apps`) or `web`; `bundleId` of a white-label tenant app adds that tenant's branding.","tags":["meta"],"security":[],"parameters":[{"name":"appId","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-z][a-z0-9-]{0,31}$"}},{"name":"bundleId","in":"query","required":false,"description":"iOS bundle id or Android package: resolves a white-label app to its tenant.","schema":{"description":"iOS bundle id or Android package: resolves a white-label app to its tenant.","type":"string","maxLength":155,"pattern":"^[A-Za-z][A-Za-z0-9-]*(\\.[A-Za-z0-9-]+)+$"}}],"responses":{"200":{"description":"Get client configuration (versions, features, sign-in client ids)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppConfig"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"Rarely: it describes app versions and sign-in client ids for the official apps."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/tenants/{slug}":{"get":{"operationId":"public.tenant","summary":"Get a tenant's public profile by slug","description":"Unknown, reserved and inactive workspaces answer 404 TENANT_NOT_FOUND. Read without caching so a closed workspace disappears immediately.","tags":["public"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}}],"responses":{"200":{"description":"Get a tenant's public profile by slug","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicTenantResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To read a tenant's public name and description from its slug."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/domains/{host}":{"get":{"operationId":"public.domain","summary":"Find the tenant behind a verified custom domain","description":"Unknown, unverified or inactive hosts answer 404 TENANT_NOT_FOUND. Successful lookups must not be cached across requests.","tags":["public"],"security":[],"parameters":[{"name":"host","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":253,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$","description":"A host name, e.g. book.example.com."}}],"responses":{"200":{"description":"Find the tenant behind a verified custom domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicDomainResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"Rarely: it maps a custom domain to the tenant slug."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}":{"get":{"operationId":"tenants.get","summary":"Get a tenant","tags":["tenants"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"Get a tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantsGetResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-agent":{"access":"agent","whenToUse":"To read the tenant's name, slug, time zone and locale."},"x-agent-ask-first":false,"x-agent-reversible":true},"patch":{"operationId":"tenants.update","summary":"Update a tenant's settings","tags":["tenants"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantsUpdateRequest"}}}},"responses":{"200":{"description":"Update a tenant's settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantsUpdateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"tenant.manage","x-agent":{"access":"agent","whenToUse":"When the person asks to rename the tenant or change its time zone or locale.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/members":{"get":{"operationId":"members.list","summary":"List a tenant's members","tags":["members"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"List a tenant's members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MembersListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"members.view","x-agent":{"access":"agent","whenToUse":"To see who is on the team and their roles."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/roles":{"get":{"operationId":"roles.list","summary":"List the roles of a tenant (platform and vertical roles)","description":"`assignable` is true when the caller may give the role: you can never give access you do not have.","tags":["members"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"List the roles of a tenant (platform and vertical roles)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolesListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"members.view","x-agent":{"access":"agent","whenToUse":"To explain what each role can do, or before suggesting a role change."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/invites":{"get":{"operationId":"invites.list","summary":"List pending invites","tags":["members"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"List pending invites","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitesListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"members.view","x-agent":{"access":"agent","whenToUse":"To see who has been invited but has not joined yet."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/audit-log":{"get":{"operationId":"audit.list","summary":"Read a tenant's audit log (newest first)","tags":["audit"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"action","in":"query","required":false,"description":"Only entries with this action.","schema":{"description":"Only entries with this action.","type":"string","maxLength":100,"pattern":"^[a-z][a-z0-9_.]*$"}}],"responses":{"200":{"description":"Read a tenant's audit log (newest first)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"audit.view","x-agent":{"access":"agent","whenToUse":"When the person asks who changed something, or what happened recently."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/media/uploads":{"post":{"operationId":"media.createUpload","summary":"Start an upload (returns a presigned POST)","description":"Announce the file (type and exact size in bytes), then POST it to `upload.url` with `upload.fields` within 10 minutes, then call media.complete. Images (JPEG, PNG, WebP, GIF) up to 10 MB, PDFs up to 25 MB, videos (MP4, MOV) up to 200 MB.","tags":["media"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaCreateUploadRequest"}}}},"responses":{"201":{"description":"Start an upload (returns a presigned POST)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaCreateUploadResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"413":{"description":"MEDIA_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"media.manage","x-agent":{"access":"agent","whenToUse":"To store a file for the workspace (first step; then send the file and call media.complete).","whenNotToUse":"Never make a file public unless the person asked for a public file (logo, product photo).","askFirst":false,"reversible":true},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/media/uploads/{uploadId}/complete":{"post":{"operationId":"media.complete","summary":"Finish an upload: check the file and store it","description":"Checks that the file arrived with the announced size and type (its first bytes must match the type), then stores it as a media item. Calling it again returns the same item.","tags":["media"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"uploadId","in":"path","required":true,"schema":{"type":"string","pattern":"^upl_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `upl_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"201":{"description":"Finish an upload: check the file and store it","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaCompleteResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"UPLOAD_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"UPLOAD_INCOMPLETE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"MEDIA_REJECTED, IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"media.manage","x-agent":{"access":"agent","whenToUse":"After sending the file to the upload URL.","askFirst":false,"reversible":true},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/media":{"get":{"operationId":"media.list","summary":"List the workspace's files (newest first)","tags":["media"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["image","document","video"]}},{"name":"visibility","in":"query","required":false,"description":"`public`: served by the CDN at a permanent URL anyone can open (logos, product photos). `private`: only through short-lived signed links (documents, anything personal).","schema":{"type":"string","enum":["public","private"],"description":"`public`: served by the CDN at a permanent URL anyone can open (logos, product photos). `private`: only through short-lived signed links (documents, anything personal)."}}],"responses":{"200":{"description":"List the workspace's files (newest first)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"media.view","x-agent":{"access":"agent","whenToUse":"To find a file the person mentions."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/media/{mediaId}":{"get":{"operationId":"media.get","summary":"Get a file (with a fresh link for private files)","tags":["media"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"string","pattern":"^ast_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ast_` prefix."}}],"responses":{"200":{"description":"Get a file (with a fresh link for private files)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaGetResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"MEDIA_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"media.view","x-agent":{"access":"agent","whenToUse":"To get a link to one file."},"x-agent-ask-first":false,"x-agent-reversible":true},"delete":{"operationId":"media.delete","summary":"Delete a file","description":"The file is removed from storage and from the CDN; links to it stop working.","tags":["media"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"mediaId","in":"path","required":true,"schema":{"type":"string","pattern":"^ast_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ast_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"MEDIA_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"media.manage","x-agent":{"access":"agent","whenToUse":"When the person explicitly asks to delete a file.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/domains":{"get":{"operationId":"domains.list","summary":"List the workspace's custom domains","tags":["domains"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"List the workspace's custom domains","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainsListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"settings.manage","x-agent":{"access":"agent","whenToUse":"To see which custom domains are connected and what DNS they still need."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"domains.add","summary":"Connect a custom domain","description":"Creates a pending claim with its own ownership TXT record plus routing instructions. Add both, then call domains.verify. Adding a domain the workspace already has returns its claim unchanged. Other workspaces may hold independent pending claims until one verifies; only a verified owner or another Vercel project blocks Add.","tags":["domains"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainsAddRequest"}}}},"responses":{"201":{"description":"Connect a custom domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainsAddResponse"}}}},"400":{"description":"DOMAIN_NOT_ALLOWED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"DOMAIN_TAKEN, DOMAIN_LIMIT_REACHED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"CUSTOM_DOMAINS_UNAVAILABLE, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"settings.manage","x-agent":{"access":"agent","whenToUse":"When the person wants their public pages on a domain they own.","whenNotToUse":"DNS changes happen at the domain owner’s provider: say what to add, then verify.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/domains/{domainId}/verify":{"post":{"operationId":"domains.verify","summary":"Check the DNS records of a custom domain","description":"Requires this claim’s ownership TXT value plus verified and configured Vercel routing. Missing TXT or DNS lookup failures leave the claim pending with a problem. The first claim to verify wins and removes other workspaces’ pending claims; their ids then return DOMAIN_NOT_FOUND. Only verified claims serve public pages.","tags":["domains"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"domainId","in":"path","required":true,"schema":{"type":"string","pattern":"^dom_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `dom_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"200":{"description":"Check the DNS records of a custom domain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainsVerifyResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"DOMAIN_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"CUSTOM_DOMAINS_UNAVAILABLE, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"settings.manage","x-agent":{"access":"agent","whenToUse":"After the person says they added the DNS records.","askFirst":false,"reversible":true},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/domains/{domainId}":{"delete":{"operationId":"domains.remove","summary":"Disconnect a custom domain","description":"Removes this workspace’s claim. The last claim also detaches the host from Vercel. Public lookups stop resolving a removed verified claim; existing site caches expire under their cache policy. DNS is not changed.","tags":["domains"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"domainId","in":"path","required":true,"schema":{"type":"string","pattern":"^dom_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `dom_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"DOMAIN_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"CUSTOM_DOMAINS_UNAVAILABLE, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"settings.manage","x-agent":{"access":"agent","whenToUse":"When the person explicitly asks to disconnect a domain.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/agent/guide":{"get":{"operationId":"agent.guide","summary":"The guide for AI agents (markdown by default, JSON with ?format=json)","tags":["agent"],"security":[],"parameters":[{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["markdown","json"]}}],"responses":{"200":{"description":"The guide for AI agents (markdown by default, JSON with ?format=json)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentGuide"}},"text/markdown":{"schema":{"type":"string"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"First: it explains how to connect, what each operation is for, and when to ask the person."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/agent/openapi.json":{"get":{"operationId":"agent.openapi","summary":"OpenAPI 3.1 document of the operations an agent may call","tags":["agent"],"security":[],"responses":{"200":{"description":"OpenAPI 3.1 document of the operations an agent may call","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentOpenapiResponse"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To generate tool definitions; `x-agent-*` fields say when to ask the person first."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/billing/plans":{"get":{"operationId":"billing.plans","summary":"List the plans tenants can subscribe to","description":"Served from the product configuration; never touches the database. Safe to cache.","tags":["billing"],"security":[],"responses":{"200":{"description":"List the plans tenants can subscribe to","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlansResponse"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To compare plans, their prices and what each one includes."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/billing/subscription":{"get":{"operationId":"billing.subscription","summary":"Get the tenant's plan, subscription status and entitlements","description":"Kept in sync by Stripe webhooks. `refresh=true` also asks Stripe right away (after returning from Checkout).","tags":["billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"refresh","in":"query","required":false,"description":"`true` re-reads the subscription from Stripe first.","schema":{"description":"`true` re-reads the subscription from Stripe first.","type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Get the tenant's plan, subscription status and entitlements","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSubscriptionResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"STRIPE_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-agent":{"access":"agent","whenToUse":"To check the tenant's plan, whether it is paid up, and what it includes."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/payments/account":{"get":{"operationId":"payments.account","summary":"Get the tenant's payments account and whether it can take payments","description":"Kept in sync by Stripe webhooks; `refresh=true` also asks Stripe right away (e.g. after onboarding). `enabled: false` means this product or environment takes no payments.","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"refresh","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Get the tenant's payments account and whether it can take payments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsAccountResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"STRIPE_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.manage","x-agent":{"access":"agent","whenToUse":"To check whether the tenant can take payments, or what Stripe still needs."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/payments/customers":{"post":{"operationId":"payments.createCustomer","summary":"Add one of the tenant's customers (to keep a card on file)","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsCreateCustomerRequest"}}}},"responses":{"201":{"description":"Add one of the tenant's customers (to keep a card on file)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsCreateCustomerResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"PAYMENTS_NOT_ENABLED, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"PAYMENTS_ACCOUNT_MISSING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"STRIPE_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"STRIPE_NOT_CONFIGURED, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.charge","x-agent":{"access":"agent","whenToUse":"Before saving a card for a customer of the tenant, when your vertical has none for them yet.","askFirst":false,"reversible":false},"x-agent-ask-first":false,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/payments/customers/{customerId}":{"get":{"operationId":"payments.getCustomer","summary":"Get a customer and their card on file","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"customerId","in":"path","required":true,"schema":{"type":"string","pattern":"^pcu_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pcu_` prefix."}}],"responses":{"200":{"description":"Get a customer and their card on file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGetCustomerResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"PAYMENTS_NOT_ENABLED, PAYMENT_CUSTOMER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.charge","x-agent":{"access":"agent","whenToUse":"To see whether a customer has a card on file before charging it."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/payments/charges":{"post":{"operationId":"payments.create","summary":"Take a payment on the tenant's account (direct charge)","description":"With `offSession: true` the customer’s card on file is charged now (no-show fee, deposit); the answer says whether it succeeded or failed. Otherwise answers a `confirmation` to finish with Stripe.js while the customer is present; `saveCard` also keeps that card on file. The product's application fee (default 0) is added.","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsCreateRequest"}}}},"responses":{"201":{"description":"Take a payment on the tenant's account (direct charge)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsCreateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"PAYMENTS_NOT_ENABLED, PAYMENT_CUSTOMER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"PAYMENTS_ACCOUNT_MISSING, PAYMENTS_ACCOUNT_NOT_READY, PAYMENT_CARD_MISSING","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"STRIPE_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"STRIPE_NOT_CONFIGURED, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.charge","x-agent":{"access":"agent","whenToUse":"When the person asks to charge a customer, e.g. a no-show fee to the card on file.","whenNotToUse":"Never to charge a card the customer did not agree to have charged.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/payments/charges/{paymentId}":{"get":{"operationId":"payments.get","summary":"Get a payment","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"paymentId","in":"path","required":true,"schema":{"type":"string","pattern":"^pay_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pay_` prefix."}}],"responses":{"200":{"description":"Get a payment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsGetResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"PAYMENTS_NOT_ENABLED, PAYMENT_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.charge","x-agent":{"access":"agent","whenToUse":"To check whether a payment succeeded, failed or was refunded."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/payments/charges/{paymentId}/refunds":{"post":{"operationId":"payments.refund","summary":"Refund a payment, fully or in part","tags":["payments"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"paymentId","in":"path","required":true,"schema":{"type":"string","pattern":"^pay_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pay_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsRefundRequest"}}}},"responses":{"200":{"description":"Refund a payment, fully or in part","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsRefundResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"PAYMENTS_NOT_ENABLED, PAYMENT_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"PAYMENT_NOT_REFUNDABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"502":{"description":"STRIPE_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"STRIPE_NOT_CONFIGURED, UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"payments.refund","x-agent":{"access":"agent","whenToUse":"When the person asks to refund a payment.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/notes":{"get":{"operationId":"notes.list","summary":"List notes (newest first)","tags":["notes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"List notes (newest first)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"notes.view","x-agent":{"access":"agent","whenToUse":"To find the team's notes before reading or changing one."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"notes.create","summary":"Create a note","tags":["notes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesCreateRequest"}}}},"responses":{"201":{"description":"Create a note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesCreateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"PLAN_UPGRADE_REQUIRED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"notes.manage","x-agent":{"access":"agent","whenToUse":"When the person asks you to write something down for the team.","askFirst":false,"reversible":true},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/notes/{noteId}":{"get":{"operationId":"notes.get","summary":"Get a note","tags":["notes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"noteId","in":"path","required":true,"schema":{"type":"string","pattern":"^nte_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `nte_` prefix."}}],"responses":{"200":{"description":"Get a note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesGetResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"NOTE_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"notes.view","x-agent":{"access":"agent","whenToUse":"To read one note in full."},"x-agent-ask-first":false,"x-agent-reversible":true},"patch":{"operationId":"notes.update","summary":"Change a note","tags":["notes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"noteId","in":"path","required":true,"schema":{"type":"string","pattern":"^nte_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `nte_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesUpdateRequest"}}}},"responses":{"200":{"description":"Change a note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotesUpdateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"NOTE_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"notes.manage","x-agent":{"access":"agent","whenToUse":"When the person asks you to edit a note.","whenNotToUse":"Never to rewrite a note the person did not ask about: earlier text is not kept.","askFirst":false,"reversible":false},"x-agent-ask-first":false,"x-agent-reversible":false},"delete":{"operationId":"notes.delete","summary":"Delete a note","tags":["notes"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"noteId","in":"path","required":true,"schema":{"type":"string","pattern":"^nte_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `nte_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"NOTE_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"notes.manage","x-agent":{"access":"agent","whenToUse":"When the person explicitly asks to delete a note.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/locations":{"get":{"operationId":"booking.listLocations","summary":"List the shop's locations","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"List the shop's locations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListLocationsResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To find a location id or a location time zone."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"booking.createLocation","summary":"Add a location","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateLocationRequest"}}}},"responses":{"201":{"description":"Add a location","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateLocationResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/locations/{locationId}":{"patch":{"operationId":"booking.updateLocation","summary":"Change a location","description":"Changing the time zone moves future availability; booked appointments keep their instants.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateLocationRequest"}}}},"responses":{"200":{"description":"Change a location","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateLocationResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/services":{"get":{"operationId":"booking.listServices","summary":"List services (the menu), including ones not offered online","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"List services (the menu), including ones not offered online","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListServicesResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To find a service id, its duration, price and who performs it."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"booking.createService","summary":"Add a service","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateServiceRequest"}}}},"responses":{"201":{"description":"Add a service","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateServiceResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/services/{serviceId}":{"patch":{"operationId":"booking.updateService","summary":"Change a service","description":"Booked appointments keep the name, duration and price they were booked with.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"serviceId","in":"path","required":true,"schema":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateServiceRequest"}}}},"responses":{"200":{"description":"Change a service","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateServiceResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"SERVICE_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true},"delete":{"operationId":"booking.archiveService","summary":"Remove a service from the menu","description":"The service is archived, not deleted: past and upcoming appointments keep it.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"serviceId","in":"path","required":true,"schema":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"SERVICE_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner explicitly removes a service.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/staff":{"get":{"operationId":"booking.listStaff","summary":"List staff members","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"List staff members","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListStaffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To find a staff id and what they perform."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"booking.createStaff","summary":"Add a staff member","description":"A profile can exist before the person has a login; link one later with membershipId.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateStaffRequest"}}}},"responses":{"201":{"description":"Add a staff member","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateStaffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"SERVICE_NOT_FOUND, MEMBER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"MEMBERSHIP_ALREADY_LINKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/staff/{staffId}":{"patch":{"operationId":"booking.updateStaff","summary":"Change a staff member (profile, login link, services performed)","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"staffId","in":"path","required":true,"schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateStaffRequest"}}}},"responses":{"200":{"description":"Change a staff member (profile, login link, services performed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdateStaffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"STAFF_NOT_FOUND, SERVICE_NOT_FOUND, MEMBER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"MEMBERSHIP_ALREADY_LINKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true},"delete":{"operationId":"booking.archiveStaff","summary":"Archive a staff member who left","description":"Refused while they have upcoming confirmed appointments. History keeps the profile.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"staffId","in":"path","required":true,"schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"STAFF_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"STAFF_HAS_APPOINTMENTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner says someone left.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/policy":{"get":{"operationId":"booking.getPolicy","summary":"Get the shop's booking policy","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"responses":{"200":{"description":"Get the shop's booking policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetPolicyResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To explain notice, cancellation, reminder or fee rules."},"x-agent-ask-first":false,"x-agent-reversible":true},"patch":{"operationId":"booking.updatePolicy","summary":"Change the shop's booking policy","description":"Applies to new bookings. Existing appointments keep the rules they were booked under.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingUpdatePolicyRequest"}}}},"responses":{"200":{"description":"Change the shop's booking policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetPolicyResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.setup.manage","x-agent":{"access":"agent","whenToUse":"When the owner asks you to change how the shop is set up.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/staff/{staffId}/hours":{"get":{"operationId":"booking.getStaffHours","summary":"Get a staff member's weekly hours","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"staffId","in":"path","required":true,"schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}}],"responses":{"200":{"description":"Get a staff member's weekly hours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetStaffHoursResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"STAFF_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To see when someone works each week."},"x-agent-ask-first":false,"x-agent-reversible":true},"put":{"operationId":"booking.setStaffHours","summary":"Replace a staff member's weekly hours","description":"Windows are local minutes-of-day in the location's time zone, so 9:00-17:00 stays 9:00-17:00 across DST. Booked appointments are not moved.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"staffId","in":"path","required":true,"schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingSetStaffHoursRequest"}}}},"responses":{"200":{"description":"Replace a staff member's weekly hours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetStaffHoursResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"STAFF_NOT_FOUND, LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"HOURS_OVERLAP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.schedule.manage","x-agent":{"access":"agent","whenToUse":"When the owner tells you when someone works, is away, or when the shop is closed.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/locations/{locationId}/hours":{"get":{"operationId":"booking.getLocationHours","summary":"Get a location's opening hours","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}}],"responses":{"200":{"description":"Get a location's opening hours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetLocationHoursResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To see when the shop is open."},"x-agent-ask-first":false,"x-agent-reversible":true},"put":{"operationId":"booking.setLocationHours","summary":"Replace a location's opening hours","description":"When a location has opening hours, staff are bookable there only inside them. Empty = no limit.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"locationId","in":"path","required":true,"schema":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingSetLocationHoursRequest"}}}},"responses":{"200":{"description":"Replace a location's opening hours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingGetLocationHoursResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"HOURS_OVERLAP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.schedule.manage","x-agent":{"access":"agent","whenToUse":"When the owner tells you when someone works, is away, or when the shop is closed.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/time-off":{"get":{"operationId":"booking.listTimeOff","summary":"List time off and closures overlapping some dates","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"from","in":"query","required":true,"description":"Calendar date YYYY-MM-DD, read in the location's time zone.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date YYYY-MM-DD, read in the location's time zone."}},{"name":"to","in":"query","required":true,"description":"Inclusive; at most 366 days after `from`.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive; at most 366 days after `from`."}},{"name":"staffId","in":"query","required":false,"description":"Id with the `stf_` prefix.","schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}},{"name":"locationId","in":"query","required":false,"description":"Id with the `loc_` prefix.","schema":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}}],"responses":{"200":{"description":"List time off and closures overlapping some dates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListTimeOffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To see who is away or when the shop is closed."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"booking.createTimeOff","summary":"Add time off (a staff member) or a closure (a location)","description":"All-day entries are local dates read in each location's zone; timed entries are instants. Booked appointments are not cancelled: check the calendar for conflicts.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateTimeOffRequest"}}}},"responses":{"201":{"description":"Add time off (a staff member) or a closure (a location)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateTimeOffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"STAFF_NOT_FOUND, LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.schedule.manage","x-agent":{"access":"agent","whenToUse":"When the owner tells you when someone works, is away, or when the shop is closed.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/time-off/{timeOffId}":{"delete":{"operationId":"booking.deleteTimeOff","summary":"Remove time off or a closure","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"timeOffId","in":"path","required":true,"schema":{"type":"string","pattern":"^tof_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `tof_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"responses":{"204":{"description":"No content"},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TIME_OFF_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.schedule.manage","x-agent":{"access":"agent","whenToUse":"When the owner tells you when someone works, is away, or when the shop is closed.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/availability":{"get":{"operationId":"booking.availability","summary":"Open slots for a service, for the front desk","description":"Like the public availability, but includes staff who are not bookable online and ignores minimum notice. Days are local dates in each location's zone; DST is handled per date.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"serviceId","in":"query","required":true,"description":"Id with the `svc_` prefix.","schema":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},{"name":"staffId","in":"query","required":false,"description":"Omit for any staff member who performs the service.","schema":{"description":"Omit for any staff member who performs the service.","type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"locationId","in":"query","required":false,"description":"Omit for every location.","schema":{"description":"Omit for every location.","type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"from","in":"query","required":true,"description":"First local date.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"First local date."}},{"name":"to","in":"query","required":true,"description":"Last local date (inclusive); at most 31 days in all.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Last local date (inclusive); at most 31 days in all."}}],"responses":{"200":{"description":"Open slots for a service, for the front desk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingAvailabilityResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"SERVICE_NOT_FOUND, LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"SERVICE_NOT_OFFERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"Before booking or moving an appointment, to find a free time."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/holds":{"post":{"operationId":"booking.createHold","summary":"Hold a time while the front desk enters the client","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry-safe key (e.g. a UUID). A repeated key with the same request replays the first answer.","schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateHoldRequest"}}}},"responses":{"201":{"description":"Hold a time while the front desk enters the client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateHoldResponse"}}}},"400":{"description":"LOCATION_REQUIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"SERVICE_NOT_FOUND, STAFF_NOT_FOUND, LOCATION_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"SERVICE_NOT_OFFERED, SLOT_UNAVAILABLE, SLOT_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"422":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.appointments.manage","x-agent":{"access":"agent","whenToUse":"First step of booking for the shop: hold the time, then book it with the client.","askFirst":false,"reversible":true},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/appointments":{"post":{"operationId":"booking.createAppointment","summary":"Book a held time for a client","description":"Booking the same hold again returns the same appointment. Emails the client a confirmation and schedules reminders unless notifyCustomer is false. New contact input requires booking.clients.contact; internalNote requires booking.clients.notes. Contact/private-note visibility is checked on every answer.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateAppointmentRequest"}}}},"responses":{"201":{"description":"Book a held time for a client","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateAppointmentResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"HOLD_NOT_FOUND, CUSTOMER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"BOOKING_HOLD_REFRESH_REQUIRED, BOOKING_DEPOSIT_REQUIRED, SLOT_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.appointments.manage","x-agent":{"access":"agent","whenToUse":"After createHold, once you have the client and the shop agreed to the booking.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true},"get":{"operationId":"booking.listAppointments","summary":"Appointments starting on some dates (the calendar)","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"from","in":"query","required":true,"description":"First date (UTC).","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"First date (UTC)."}},{"name":"to","in":"query","required":true,"description":"Last date (UTC, inclusive); at most 62 days in all.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Last date (UTC, inclusive); at most 62 days in all."}},{"name":"staffId","in":"query","required":false,"description":"Id with the `stf_` prefix.","schema":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}},{"name":"locationId","in":"query","required":false,"description":"Id with the `loc_` prefix.","schema":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]}}],"responses":{"200":{"description":"Appointments starting on some dates (the calendar)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListAppointmentsResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To read the shop's calendar for a day or a week."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/appointments/{appointmentId}":{"get":{"operationId":"booking.getAppointment","summary":"Get an appointment","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"appointmentId","in":"path","required":true,"schema":{"type":"string","pattern":"^apt_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `apt_` prefix."}}],"responses":{"200":{"description":"Get an appointment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateAppointmentResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"APPOINTMENT_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.view","x-agent":{"access":"agent","whenToUse":"To read one appointment and its current version."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/appointments/{appointmentId}/reschedule":{"post":{"operationId":"booking.rescheduleAppointment","summary":"Move an appointment to another time (or staff member)","description":"The appointment keeps its id; its version bumps, reminders move with it and the client is told.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"appointmentId","in":"path","required":true,"schema":{"type":"string","pattern":"^apt_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `apt_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingRescheduleAppointmentRequest"}}}},"responses":{"200":{"description":"Move an appointment to another time (or staff member)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateAppointmentResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"APPOINTMENT_NOT_FOUND, STAFF_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"APPOINTMENT_NOT_CHANGEABLE, VERSION_CONFLICT, SLOT_UNAVAILABLE, SLOT_TAKEN, SERVICE_NOT_OFFERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.appointments.manage","x-agent":{"access":"agent","whenToUse":"When the shop or the client asks to move a booking (check availability first).","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/appointments/{appointmentId}/cancel":{"post":{"operationId":"booking.cancelAppointment","summary":"Cancel an appointment","description":"Frees the time and stops reminders. A client's cancellation inside the policy window is marked late. Cancelling twice answers the cancelled appointment.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"appointmentId","in":"path","required":true,"schema":{"type":"string","pattern":"^apt_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `apt_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCancelAppointmentRequest"}}}},"responses":{"200":{"description":"Cancel an appointment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingCreateAppointmentResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"APPOINTMENT_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"APPOINTMENT_NOT_CHANGEABLE, VERSION_CONFLICT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.appointments.manage","x-agent":{"access":"agent","whenToUse":"When asked to cancel a booking.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/customers":{"get":{"operationId":"booking.listCustomers","summary":"Search the shop's clients","description":"Compatibility route for the client directory. Requires booking.clients.view; email/phone are hidden and cannot be searched without booking.clients.contact. New clients should use booking.clientsList.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"query","in":"query","required":false,"description":"Matches the start of a name, email or phone.","schema":{"description":"Matches the start of a name, email or phone.","type":"string","minLength":1,"maxLength":100}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Search the shop's clients","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingListCustomersResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.clients.view","x-agent":{"access":"agent","whenToUse":"To find an existing client before booking for them."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/tenants/{slug}/booking/locations":{"get":{"operationId":"booking.publicLocations","summary":"A shop's locations open for online booking","tags":["booking","public"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}}],"responses":{"200":{"description":"A shop's locations open for online booking","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingPublicLocationsResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To tell someone where a shop is and which time zone it books in."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/tenants/{slug}/booking/services":{"get":{"operationId":"booking.publicServices","summary":"A shop's services offered online, and its booking policy","tags":["booking","public"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}}],"responses":{"200":{"description":"A shop's services offered online, and its booking policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingPublicServicesResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To tell someone what a shop offers, for how long and at what price."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/tenants/{slug}/booking/staff":{"get":{"operationId":"booking.publicStaff","summary":"A shop's staff who take online bookings","tags":["booking","public"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}}],"responses":{"200":{"description":"A shop's staff who take online bookings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingPublicStaffResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To tell someone who works at a shop and what each person does."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/public/tenants/{slug}/booking/availability":{"get":{"operationId":"booking.publicAvailability","summary":"Open slots for a service","description":"Days are local dates in each location's time zone, DST-correct per date. Honors the shop's minimum notice and how far ahead it books.","tags":["booking","public"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}},{"name":"serviceId","in":"query","required":true,"description":"Id with the `svc_` prefix.","schema":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},{"name":"staffId","in":"query","required":false,"description":"Omit for any staff member who performs the service.","schema":{"description":"Omit for any staff member who performs the service.","type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"locationId","in":"query","required":false,"description":"Omit for every location.","schema":{"description":"Omit for every location.","type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$"}},{"name":"from","in":"query","required":true,"description":"First local date.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"First local date."}},{"name":"to","in":"query","required":true,"description":"Last local date (inclusive); at most 31 days in all.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Last local date (inclusive); at most 31 days in all."}}],"responses":{"200":{"description":"Open slots for a service","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingAvailabilityResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND, SERVICE_NOT_FOUND, LOCATION_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"SERVICE_NOT_OFFERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"public","x-agent":{"access":"public_info","whenToUse":"To find when a service can be booked."},"x-agent-ask-first":false,"x-agent-reversible":true}},"/v1/tenants/{tenantId}/booking/clients":{"get":{"operationId":"booking.clientsList","summary":"List or search the shop's client directory","description":"Newest-created clients first. Hidden contacts cannot be searched. Private fields are permission-filtered.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"limit","in":"query","required":false,"description":"Page size (default 25).","schema":{"description":"Page size (default 25).","type":"integer","minimum":1,"maximum":100}},{"name":"query","in":"query","required":false,"description":"Literal name prefix; also email/phone if visible.","schema":{"description":"Literal name prefix; also email/phone if visible.","type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"List or search the shop's client directory","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsListResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.clients.view","x-agent":{"access":"agent","whenToUse":"To find a client when acting for the shop."},"x-agent-ask-first":false,"x-agent-reversible":true},"post":{"operationId":"booking.clientsCreate","summary":"Create a client record","description":"Also requires booking.clients.view and booking.clients.contact; notes require booking.clients.notes. Duplicate live email/phone is a conflict. Does not link a login, verify contact ownership, or send a message.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsCreateRequest"}}}},"responses":{"201":{"description":"Create a client record","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsCreateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"CLIENT_CONTACT_CONFLICT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.clients.manage","x-agent":{"access":"agent","whenToUse":"When the shop asks to add a client.","askFirst":true,"reversible":false},"x-agent-ask-first":true,"x-agent-reversible":false}},"/v1/tenants/{tenantId}/booking/clients/{clientId}":{"get":{"operationId":"booking.clientsGet","summary":"Read one client and their booking history","description":"Contact details and private notes require their separate client permissions, including in history.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"clientId","in":"path","required":true,"schema":{"type":"string","pattern":"^cus_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `cus_` prefix."}},{"name":"historyCursor","in":"query","required":false,"description":"Opaque cursor from a previous page.","schema":{"type":"string","minLength":1,"maxLength":512,"description":"Opaque cursor from a previous page."}},{"name":"historyLimit","in":"query","required":false,"description":"Booking history page size; default 25.","schema":{"description":"Booking history page size; default 25.","type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Read one client and their booking history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsGetResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"CUSTOMER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.clients.view","x-agent":{"access":"agent","whenToUse":"To read a client and their prior bookings for the shop."},"x-agent-ask-first":false,"x-agent-reversible":true},"patch":{"operationId":"booking.clientsUpdate","summary":"Update client contact details or private notes","description":"Requires the current expectedVersion and booking.clients.view. Email/phone changes require booking.clients.contact; notes require booking.clients.notes. Null clears an optional field; retain a contact.","tags":["booking"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."}},{"name":"clientId","in":"path","required":true,"schema":{"type":"string","pattern":"^cus_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `cus_` prefix."}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsUpdateRequest"}}}},"responses":{"200":{"description":"Update client contact details or private notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingClientsCreateResponse"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"UNAUTHENTICATED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"CUSTOMER_NOT_FOUND, TENANT_NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"409":{"description":"CLIENT_CONTACT_CONFLICT, CLIENT_VERSION_CONFLICT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"RATE_LIMITED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"500":{"description":"INTERNAL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"UNAVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"default":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"x-auth":"tenant","x-permission":"booking.clients.manage","x-agent":{"access":"agent","whenToUse":"When the shop asks to correct a client record.","askFirst":true,"reversible":true},"x-agent-ask-first":true,"x-agent-reversible":true}}},"components":{"schemas":{"AgentGuide":{"type":"object","properties":{"product":{"type":"string"},"apiBaseUrl":{"type":"string"},"contractVersion":{"type":"string"},"authentication":{"type":"string"},"operations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"method":{"type":"string"},"path":{"type":"string"},"summary":{"type":"string"},"access":{"type":"string","enum":["agent","public_info"]},"permission":{"type":["string","null"]},"whenToUse":{"type":"string"},"whenNotToUse":{"type":["string","null"]},"askFirst":{"type":"boolean"},"reversible":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}}},"required":["id","method","path","summary","access","permission","whenToUse","whenNotToUse","askFirst","reversible","errors"]}},"errors":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"status":{"type":"integer"},"meaning":{"type":"string"},"whatToDo":{"type":"string"}},"required":["code","status","meaning","whatToDo"]}}},"required":["product","apiBaseUrl","contractVersion","authentication","operations","errors"]},"Entitlements":{"type":"object","properties":{"features":{"type":"array","items":{"type":"string"},"description":"Feature keys the plan includes, e.g. `notes.export`."},"limits":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":0},"description":"Numeric limits, e.g. `{ \"members\": 10 }`. A key that is absent has no limit."}},"required":["features","limits"]},"PlanRef":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"A plan key from the product's plans.json, e.g. `pro`."},"name":{"type":"string"}},"required":["key","name"]},"Plan":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"A plan key from the product's plans.json, e.g. `pro`."},"name":{"type":"string"},"description":{"type":"string"},"highlights":{"type":"array","items":{"type":"string"},"description":"Short selling points to show next to the price."},"price":{"anyOf":[{"type":"object","properties":{"amountMinor":{"type":"integer"},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},"interval":{"type":"string","enum":["month","year"]}},"required":["amountMinor","currency","interval"]},{"type":"null"}],"description":"Null for the free default plan."},"trialDays":{"description":"Free days before the first charge, for a first subscription.","type":["integer","null"]},"entitlements":{"$ref":"#/components/schemas/Entitlements"},"purchasable":{"type":"boolean","description":"Whether billing.checkout can start this plan here (it has a Stripe price)."}},"required":["key","name","description","highlights","price","trialDays","entitlements","purchasable"]},"Subscription":{"type":"object","properties":{"plan":{"description":"The plan in effect: the subscribed plan while it is trialing, active or past due; otherwise the default plan.","$ref":"#/components/schemas/PlanRef"},"status":{"type":"string","enum":["none","trialing","active","past_due","unpaid","canceled","incomplete","incomplete_expired","paused"],"description":"Stripe's subscription status, or `none` before the tenant's first subscription."},"subscribedPlan":{"anyOf":[{"$ref":"#/components/schemas/PlanRef"},{"type":"null"}],"description":"The Stripe subscription's plan (null before the first subscription, or for a price plans.json doesn't list)."},"currentPeriodEnd":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"When the current paid period ends (the next renewal)."},"trialEnd":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}]},"cancelAtPeriodEnd":{"type":"boolean","description":"The subscription ends at `currentPeriodEnd` instead of renewing."},"entitlements":{"description":"What the plan in effect includes.","$ref":"#/components/schemas/Entitlements"},"canOpenPortal":{"type":"boolean","description":"The tenant has a billing account, so billing.portal can open."}},"required":["plan","status","subscribedPlan","currentPeriodEnd","trialEnd","cancelAtPeriodEnd","entitlements","canOpenPortal"]},"PublicTenant":{"type":"object","properties":{"id":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."},"name":{"type":"string"},"slug":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."},"description":{"type":["string","null"]}},"required":["id","name","slug","description"]},"DnsRecord":{"type":"object","properties":{"type":{"type":"string","enum":["A","CNAME","TXT"]},"name":{"type":"string","description":"Full record name, including the product-prefixed claim ownership TXT name."},"value":{"type":"string"},"purpose":{"type":"string","enum":["routing","ownership"],"description":"`routing` points the domain at the site; `ownership` includes this claim’s TXT proof and any provider proof."}},"required":["type","name","value","purpose"]},"Domain":{"type":"object","properties":{"id":{"type":"string","pattern":"^dom_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `dom_` prefix."},"host":{"type":"string"},"status":{"type":"string","enum":["pending","verified"],"description":"Only verified domains serve the public pages."},"records":{"type":"array","items":{"$ref":"#/components/schemas/DnsRecord"},"description":"Routing and ownership DNS records to create and keep while connected."},"problem":{"description":"Why the last check did not verify the domain, in plain words.","type":["string","null"]},"verifiedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}]},"checkedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","host","status","records","problem","verifiedAt","checkedAt","createdAt"]},"TenantBrand":{"type":"object","properties":{"primary":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"onPrimary":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"surface":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"text":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"logoUrl":{"type":"string","format":"uri"}}},"Tenant":{"type":"object","properties":{"id":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."},"name":{"type":"string"},"slug":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."},"description":{"description":"Shown on the public tenant page.","type":["string","null"]},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"locale":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Z][a-z]{3})?(-([A-Z]{2}|\\d{3}))?$","description":"BCP 47 language tag, e.g. en-US."},"status":{"type":"string","enum":["active","closing","suspended","archived","deleted"]},"closedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}]},"purgeAfter":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"A closing workspace can be reopened only before this instant."},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","name","slug","description","timezone","locale","status","closedAt","purgeAfter","createdAt"]},"Member":{"type":"object","properties":{"id":{"type":"string","pattern":"^mem_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `mem_` prefix."},"user":{"type":"object","properties":{"id":{"type":"string","pattern":"^usr_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `usr_` prefix."},"name":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["id","name","email"]},"role":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,31}$","description":"Role name."},"grants":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*){1,2}$","description":"Permission, resource.action[.scope]."},"description":"Permissions added on top of the role."},"revokes":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*){1,2}$","description":"Permission, resource.action[.scope]."},"description":"Permissions removed from the role."},"permissions":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*){1,2}$","description":"Permission, resource.action[.scope]."}},"status":{"type":"string","enum":["active"]},"joinedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","user","role","grants","revokes","permissions","status","joinedAt"]},"Role":{"type":"object","properties":{"key":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,31}$","description":"Role name."},"label":{"type":"string"},"description":{"type":"string"},"permissions":{"type":"array","items":{"type":"string","pattern":"^[a-z][a-z0-9_]*(\\.[a-z][a-z0-9_]*){1,2}$","description":"Permission, resource.action[.scope]."}},"assignable":{"type":"boolean"}},"required":["key","label","description","permissions","assignable"]},"Invite":{"type":"object","properties":{"id":{"type":"string","pattern":"^inv_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `inv_` prefix."},"email":{"type":"string"},"role":{"type":"string","pattern":"^[a-z][a-z0-9_]{1,31}$","description":"Role name."},"status":{"type":"string","enum":["pending","accepted","revoked","expired"]},"invitedBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},{"type":"null"}]},"expiresAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","email","role","status","invitedBy","expiresAt","createdAt"]},"AuditEntry":{"type":"object","properties":{"id":{"type":"string","pattern":"^aud_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `aud_` prefix."},"at":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"action":{"type":"string","description":"What happened, e.g. `member.invited`, `note.deleted`."},"actor":{"type":"object","properties":{"kind":{"type":"string","enum":["user","api_key","system"]},"id":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["kind","id","name"]},"entity":{"anyOf":[{"type":"object","properties":{"kind":{"type":"string"},"id":{"type":"string"}},"required":["kind","id"]},{"type":"null"}]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["id","at","action","actor","entity","metadata"]},"Media":{"type":"object","properties":{"id":{"type":"string","pattern":"^ast_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ast_` prefix."},"kind":{"type":"string","enum":["image","document","video"]},"contentType":{"type":"string","description":"One of MediaContentType."},"size":{"type":"integer","minimum":1,"description":"Bytes."},"filename":{"description":"The name the file was uploaded with, if any.","type":["string","null"]},"visibility":{"type":"string","enum":["public","private"],"description":"`public`: served by the CDN at a permanent URL anyone can open (logos, product photos). `private`: only through short-lived signed links (documents, anything personal)."},"url":{"type":"string","format":"uri","description":"Public: the permanent CDN URL. Private: a signed link that works until `urlExpiresAt`."},"urlExpiresAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"Null for public files (their URL never expires)."},"createdBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","kind","contentType","size","filename","visibility","url","urlExpiresAt","createdBy","createdAt"]},"MediaUpload":{"type":"object","properties":{"id":{"type":"string","pattern":"^upl_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `upl_` prefix."},"method":{"type":"string","const":"POST"},"url":{"type":"string","format":"uri","description":"Send a multipart/form-data POST here: every entry of `fields`, then the file as `file`."},"fields":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Form fields to send as they are, before the file."},"expiresAt":{"type":"string","format":"date-time","description":"The file must be sent before this time (10 minutes)."}},"required":["id","method","url","fields","expiresAt"]},"Health":{"type":"object","properties":{"status":{"type":"string","const":"ok"},"version":{"type":"string","description":"Release of the running API (commit or version)."},"stage":{"type":"string","description":"`dev`, `prod` or `local`."},"contractVersion":{"type":"string","description":"Version of this API contract."}},"required":["status","version","stage","contractVersion"]},"AppConfig":{"type":"object","properties":{"minVersion":{"type":"string","description":"Older app versions must update before continuing."},"recommendedVersion":{"type":"string","description":"Older app versions should suggest an update."},"features":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"boolean"},"description":"Feature flags for this app."},"brand":{"type":"object","properties":{"name":{"type":"string"},"supportEmail":{"type":"string"},"webUrl":{"type":"string"},"appUrl":{"type":"string"}},"required":["name","supportEmail","webUrl","appUrl"]},"auth":{"type":"object","properties":{"googleClientIds":{"type":"object","properties":{"web":{"type":"string"},"ios":{"type":"string"},"android":{"type":"string"}},"description":"Google OAuth client ids by platform."},"appleAudiences":{"type":"object","properties":{"web":{"type":"string"},"ios":{"type":"string"},"android":{"type":"string"}},"description":"Sign in with Apple client ids by platform (`web` is the Services ID)."}},"required":["googleClientIds","appleAudiences"]},"tenant":{"description":"Present when `bundleId` is a white-label app of a tenant: brand the app at runtime.","type":"object","properties":{"id":{"type":"string","pattern":"^ten_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `ten_` prefix."},"slug":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."},"name":{"type":"string"},"brand":{"$ref":"#/components/schemas/TenantBrand"}},"required":["id","slug","name","brand"]}},"required":["minVersion","recommendedVersion","features","brand","auth"]},"PaymentsAccount":{"type":"object","properties":{"id":{"type":"string","description":"The Stripe connected account (acct_…). Its owner also has the full Stripe Dashboard."},"status":{"type":"string","enum":["onboarding","restricted","active","rejected","disconnected"],"description":"`onboarding`: details still to give; `restricted`: Stripe needs more or is reviewing; `active`: payments and payouts work; `rejected`: Stripe closed it; `disconnected`: the account left the platform."},"chargesEnabled":{"type":"boolean"},"payoutsEnabled":{"type":"boolean"},"detailsSubmitted":{"type":"boolean"},"requirementsDue":{"type":"array","items":{"type":"string"},"description":"Stripe requirement ids still due; onboarding collects them."},"disabledReason":{"type":["string","null"]},"country":{"type":["string","null"]},"defaultCurrency":{"anyOf":[{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","status","chargesEnabled","payoutsEnabled","detailsSubmitted","requirementsDue","disabledReason","country","defaultCurrency","createdAt","updatedAt"]},"SavedCard":{"type":"object","properties":{"brand":{"type":"string"},"last4":{"type":"string"},"expMonth":{"type":"integer"},"expYear":{"type":"integer"}},"required":["brand","last4","expMonth","expYear"]},"PaymentCustomer":{"type":"object","properties":{"id":{"type":"string","pattern":"^pcu_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pcu_` prefix."},"email":{"type":["string","null"]},"name":{"type":["string","null"]},"phone":{"type":["string","null"]},"reference":{"description":"Your own reference, e.g. the id of the client in your vertical.","type":["string","null"]},"card":{"anyOf":[{"$ref":"#/components/schemas/SavedCard"},{"type":"null"}],"description":"The card on file for later off-session charges (no-show fees)."},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","email","name","phone","reference","card","createdAt"]},"Payment":{"type":"object","properties":{"id":{"type":"string","pattern":"^pay_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pay_` prefix."},"amount":{"type":"object","properties":{"amountMinor":{"type":"integer"},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."}},"required":["amountMinor","currency"],"description":"An amount in minor units (cents) and its currency."},"applicationFeeMinor":{"type":"integer","description":"The platform's fee in minor units (0 unless the product sets one)."},"amountRefundedMinor":{"type":"integer"},"status":{"type":"string","enum":["pending","requires_action","processing","authorized","succeeded","failed","canceled"],"description":"`pending`: waiting for the customer to pay; `requires_action`: the customer must authenticate; `authorized`: held, not captured; `failed`: declined (see `failure`)."},"customerId":{"anyOf":[{"type":"string","pattern":"^pcu_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pcu_` prefix."},{"type":"null"}]},"description":{"type":["string","null"]},"reference":{"description":"Your own reference, e.g. `booking:bkg_…`.","type":["string","null"]},"offSession":{"type":"boolean","description":"Charged to the card on file without the customer present."},"failure":{"anyOf":[{"type":"object","properties":{"code":{"type":["string","null"]},"message":{"type":"string"}},"required":["code","message"]},{"type":"null"}]},"stripePaymentIntentId":{"type":"string"},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","amount","applicationFeeMinor","amountRefundedMinor","status","customerId","description","reference","offSession","failure","stripePaymentIntentId","createdAt","updatedAt"]},"StripeConfirmation":{"type":"object","properties":{"clientSecret":{"type":"string","description":"Single-use: pass it to Stripe.js; never store or log it."},"publishableKey":{"type":"string"},"accountId":{"type":"string","description":"Initialise Stripe.js with `{ stripeAccount: accountId }` (direct charges)."}},"required":["clientSecret","publishableKey","accountId"]},"Price":{"type":"object","properties":{"type":{"type":"string","enum":["fixed","from","range","free","quote"],"description":"fixed, from (a minimum), range, free, or quote (priced after a consultation)."},"amountMinor":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Price (or the minimum) in minor units, e.g. cents."},"maxAmountMinor":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Upper bound for `range` prices."},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."}},"required":["type","amountMinor","maxAmountMinor","currency"]},"Address":{"type":"object","properties":{"line1":{"type":["string","null"]},"line2":{"type":["string","null"]},"city":{"type":["string","null"]},"region":{"type":["string","null"]},"postalCode":{"type":["string","null"]},"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code."}},"required":["line1","line2","city","region","postalCode","country"]},"Location":{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"name":{"type":"string"},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"Weekly hours and all-day time off are read in this zone."},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"]},"active":{"type":"boolean","description":"Open for online booking."},"sortOrder":{"type":"integer"},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","name","timezone","address","phone","active","sortOrder","createdAt","updatedAt"]},"ProcessingGap":{"type":"object","properties":{"offsetMinutes":{"type":"integer","minimum":1,"maximum":1435,"description":"Minutes after the start when the gap begins."},"lengthMinutes":{"type":"integer","minimum":1,"maximum":1435}},"required":["offsetMinutes","lengthMinutes"],"description":"A pause inside the service (color developing): the staff member is free, the client is not."},"Service":{"type":"object","properties":{"id":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."},"name":{"type":"string"},"description":{"type":["string","null"]},"durationMinutes":{"type":"integer","description":"How long the client is booked for."},"bufferBeforeMinutes":{"type":"integer","description":"Staff time blocked before the start (preparation)."},"bufferAfterMinutes":{"type":"integer","description":"Staff time blocked after the end (cleanup)."},"processingGap":{"anyOf":[{"$ref":"#/components/schemas/ProcessingGap"},{"type":"null"}]},"price":{"$ref":"#/components/schemas/Price"},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Required deposit in minor units of the service currency (0 = none). This amount alone is not proof of payment."},"active":{"type":"boolean","description":"Offered for online booking."},"sortOrder":{"type":"integer"},"staffIds":{"type":"array","items":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"description":"Staff members who perform it."},"version":{"type":"integer"},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","name","description","durationMinutes","bufferBeforeMinutes","bufferAfterMinutes","processingGap","price","depositMinor","active","sortOrder","staffIds","version","createdAt","updatedAt"]},"StaffMember":{"type":"object","properties":{"id":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"displayName":{"type":"string"},"title":{"type":["string","null"]},"bio":{"type":["string","null"]},"bookable":{"type":"boolean","description":"Takes online bookings."},"sortOrder":{"type":"integer"},"membershipId":{"anyOf":[{"type":"string","pattern":"^mem_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `mem_` prefix."},{"type":"null"}],"description":"The login linked to this profile: it sees its own schedule."},"serviceIds":{"type":"array","items":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},"locationIds":{"type":"array","items":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"description":"Locations where the staff member has weekly hours."},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","displayName","title","bio","bookable","sortOrder","membershipId","serviceIds","locationIds","createdAt","updatedAt"]},"BookingPolicy":{"type":"object","properties":{"minNoticeMinutes":{"type":"integer","minimum":0,"maximum":43200,"description":"Online bookings start at least this long from now."},"maxAdvanceDays":{"type":"integer","minimum":1,"maximum":730,"description":"…and at most this many days ahead."},"slotIntervalMinutes":{"type":"integer","minimum":5,"maximum":240,"description":"Start times are offered on this grid from local midnight."},"holdMinutes":{"type":"integer","minimum":2,"maximum":60,"description":"How long a hold keeps a time while the client checks out."},"cancellationWindowHours":{"type":"integer","minimum":0,"maximum":720,"description":"A client cancelling later than this before the start is a late cancellation."},"rescheduleWindowHours":{"type":"integer","minimum":0,"maximum":720,"description":"Clients may move a booking until this long before it."},"reminderOffsetsMinutes":{"maxItems":3,"type":"array","items":{"type":"integer","minimum":5,"maximum":20160},"description":"Reminders, in minutes before the start (1440 = a day before)."},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},"lateCancelFeeMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Stored only: fees are not charged yet."},"noShowFeeMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Stored only: fees are not charged yet."},"allowAnyStaff":{"type":"boolean","description":"Clients may pick \"any staff member\"."},"staffCanSeeClientContact":{"type":"boolean","description":"Staff see their clients' email and phone on their schedule."},"policyText":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Shown to clients before they book."}},"required":["minNoticeMinutes","maxAdvanceDays","slotIntervalMinutes","holdMinutes","cancellationWindowHours","rescheduleWindowHours","reminderOffsetsMinutes","currency","lateCancelFeeMinor","noShowFeeMinor","allowAnyStaff","staffCanSeeClientContact","policyText"]},"Slot":{"type":"object","properties":{"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"endsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"locationId":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"The location's zone: show the time in it."},"staffIds":{"minItems":1,"type":"array","items":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."}}},"required":["startsAt","endsAt","locationId","timezone","staffIds"]},"Hold":{"type":"object","properties":{"id":{"type":"string","pattern":"^hld_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `hld_` prefix."},"status":{"type":"string","enum":["active","converted","expired","released"]},"expiresAt":{"type":"string","format":"date-time","description":"Book before this; afterwards the time is kept only if nobody took it."},"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"endsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"location":{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"name":{"type":"string"},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."}},"required":["id","name","timezone"]},"service":{"type":"object","properties":{"id":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."},"name":{"type":"string"},"durationMinutes":{"type":"integer"},"price":{"$ref":"#/components/schemas/Price"},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Required deposit in minor units of the service currency (0 = none). This amount alone is not proof of payment."}},"required":["id","name","durationMinutes","price","depositMinor"]},"staff":{"type":"object","properties":{"id":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"displayName":{"type":"string"}},"required":["id","displayName"]}},"required":["id","status","expiresAt","startsAt","endsAt","location","service","staff"]},"Customer":{"type":"object","properties":{"id":{"type":"string","pattern":"^cus_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `cus_` prefix."},"givenName":{"type":"string"},"familyName":{"type":["string","null"]},"email":{"description":"Hidden (null) on a staff schedule unless the shop shares contacts.","type":["string","null"]},"phone":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","givenName","familyName","email","phone","createdAt"]},"AppointmentService":{"type":"object","properties":{"service":{"type":"object","properties":{"id":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."},"name":{"type":"string"}},"required":["id","name"]},"staff":{"type":"object","properties":{"id":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"displayName":{"type":"string"}},"required":["id","displayName"]},"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"endsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"durationMinutes":{"type":"integer"},"price":{"description":"As booked: later price changes do not apply.","$ref":"#/components/schemas/Price"}},"required":["service","staff","startsAt","endsAt","durationMinutes","price"]},"Appointment":{"type":"object","properties":{"id":{"type":"string","pattern":"^apt_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `apt_` prefix."},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"source":{"type":"string","enum":["web","owner","api","agent","import"]},"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"endsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"location":{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"name":{"type":"string"}},"required":["id","name"]},"customer":{"$ref":"#/components/schemas/Customer"},"services":{"minItems":1,"type":"array","items":{"$ref":"#/components/schemas/AppointmentService"}},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"The required deposit as booked; later service edits do not change it."},"depositPaidMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Verified deposit credit still held for this appointment, excluding observed refunds."},"customerNote":{"type":["string","null"]},"internalNote":{"type":["string","null"]},"policy":{"description":"The rules this appointment was booked under.","$ref":"#/components/schemas/BookingPolicy"},"cancellation":{"anyOf":[{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"by":{"type":"string","enum":["customer","business","system"]},"reason":{"type":["string","null"]},"late":{"type":"boolean","description":"Inside the policy's cancellation window (a fee may apply later)."}},"required":["at","by","reason","late"]},{"type":"null"}]},"version":{"type":"integer","description":"Bumps on every change; send it back as expectedVersion."},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","status","source","startsAt","endsAt","timezone","location","customer","services","depositMinor","depositPaidMinor","customerNote","internalNote","policy","cancellation","version","createdAt","updatedAt"]},"HoursWindow":{"type":"object","properties":{"weekday":{"type":"integer","minimum":1,"maximum":7,"description":"ISO weekday: 1 = Monday … 7 = Sunday."},"startMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Minutes after local midnight (540 = 9:00, 1440 = the end of the day)."},"endMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Exclusive; 1440 = until midnight."}},"required":["weekday","startMinute","endMinute"]},"StaffHoursWindow":{"type":"object","properties":{"locationId":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"weekday":{"type":"integer","minimum":1,"maximum":7,"description":"ISO weekday: 1 = Monday … 7 = Sunday."},"startMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Minutes after local midnight (540 = 9:00, 1440 = the end of the day)."},"endMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Exclusive; 1440 = until midnight."}},"required":["locationId","weekday","startMinute","endMinute"]},"TimeOff":{"type":"object","properties":{"id":{"type":"string","pattern":"^tof_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `tof_` prefix."},"staffId":{"anyOf":[{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},{"type":"null"}],"description":"Set for a staff member's time off."},"locationId":{"anyOf":[{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},{"type":"null"}],"description":"Set for a location's closure."},"allDay":{"type":"boolean"},"startDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date YYYY-MM-DD, read in the location's time zone."},{"type":"null"}],"description":"All day: first local date."},"endDate":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date YYYY-MM-DD, read in the location's time zone."},{"type":"null"}],"description":"All day: last local date (inclusive)."},"startsAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"Timed: start instant."},"endsAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"Timed: end instant (exclusive)."},"reason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","staffId","locationId","allDay","startDate","endDate","startsAt","endsAt","reason","createdAt"]},"BookingClient":{"type":"object","properties":{"id":{"type":"string","pattern":"^cus_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `cus_` prefix."},"givenName":{"type":"string"},"familyName":{"type":["string","null"]},"email":{"description":"Hidden (null) on a staff schedule unless the shop shares contacts.","type":["string","null"]},"phone":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"notes":{"description":"Shop-private notes; null without booking.clients.notes.","type":["string","null"]},"source":{"type":"string","enum":["online","owner","import","api"]},"version":{"type":"integer","minimum":1,"description":"Send as expectedVersion when updating this client."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"visibility":{"type":"object","properties":{"contact":{"type":"boolean","description":"Email and phone are visible with booking.clients.contact."},"notes":{"type":"boolean","description":"Private client and appointment notes are visible with booking.clients.notes."}},"required":["contact","notes"]}},"required":["id","givenName","familyName","email","phone","createdAt","notes","source","version","updatedAt","visibility"]},"PublicLocation":{"type":"object","properties":{"id":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"name":{"type":"string"},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"address":{"$ref":"#/components/schemas/Address"},"phone":{"type":["string","null"]}},"required":["id","name","timezone","address","phone"]},"PublicService":{"type":"object","properties":{"id":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."},"name":{"type":"string"},"description":{"type":["string","null"]},"durationMinutes":{"type":"integer"},"price":{"$ref":"#/components/schemas/Price"},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Required deposit in minor units of the service currency (0 = none). This amount alone is not proof of payment."},"staffIds":{"type":"array","items":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"description":"Bookable staff members who perform it."}},"required":["id","name","description","durationMinutes","price","depositMinor","staffIds"]},"PublicStaffMember":{"type":"object","properties":{"id":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"displayName":{"type":"string"},"title":{"type":["string","null"]},"bio":{"type":["string","null"]},"serviceIds":{"type":"array","items":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}},"locationIds":{"type":"array","items":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."}}},"required":["id","displayName","title","bio","serviceIds","locationIds"]},"PublicPolicy":{"type":"object","properties":{"minNoticeMinutes":{"type":"integer"},"maxAdvanceDays":{"type":"integer"},"allowAnyStaff":{"type":"boolean"},"cancellationWindowHours":{"type":"integer"},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},"lateCancelFeeMinor":{"type":"integer"},"noShowFeeMinor":{"type":"integer"},"policyText":{"type":["string","null"]}},"required":["minNoticeMinutes","maxAdvanceDays","allowAnyStaff","cancellationWindowHours","currency","lateCancelFeeMinor","noShowFeeMinor","policyText"]},"Note":{"type":"object","properties":{"id":{"type":"string","pattern":"^nte_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `nte_` prefix."},"title":{"type":"string"},"body":{"type":"string"},"createdBy":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"updatedAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."}},"required":["id","title","body","createdBy","createdAt","updatedAt"]},"ErrorEnvelope":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","pattern":"^[A-Z][A-Z0-9_]*$"},"message":{"type":"string"},"outcome":{"type":"string","enum":["not_committed","committed","unknown"]},"remediation":{"type":"object","properties":{"action":{"type":"string","pattern":"^[a-z][a-z0-9_]*$"},"message":{"type":"string","maxLength":500},"retryAfterSeconds":{"type":"integer","minimum":0,"maximum":86400},"field":{"type":"string","maxLength":200}},"required":["action"],"additionalProperties":{},"description":"What the caller can do about the failure."},"requestId":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Dotted path of the offending field, e.g. `body.email`."},"message":{"type":"string"}},"required":["path","message"]}}},"required":["code","message","outcome"],"additionalProperties":{}}},"required":["error"],"description":"Every non-2xx response has this body."},"PublicTenantResponse":{"type":"object","properties":{"tenant":{"$ref":"#/components/schemas/PublicTenant"}},"required":["tenant"]},"PublicDomainResponse":{"type":"object","properties":{"tenant":{"type":"object","properties":{"slug":{"type":"string","minLength":2,"maxLength":48,"pattern":"^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$","description":"Lowercase letters, digits and single dashes."}},"required":["slug"]}},"required":["tenant"]},"TenantsGetResponse":{"type":"object","properties":{"tenant":{"$ref":"#/components/schemas/Tenant"}},"required":["tenant"]},"TenantsUpdateResponse":{"type":"object","properties":{"tenant":{"$ref":"#/components/schemas/Tenant"}},"required":["tenant"]},"MembersListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"RolesListResponse":{"type":"object","properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/Role"}}},"required":["roles"]},"InvitesListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"AuditListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"MediaCreateUploadResponse":{"type":"object","properties":{"upload":{"$ref":"#/components/schemas/MediaUpload"}},"required":["upload"]},"MediaCompleteResponse":{"type":"object","properties":{"media":{"$ref":"#/components/schemas/Media"}},"required":["media"]},"MediaListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Media"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"MediaGetResponse":{"type":"object","properties":{"media":{"$ref":"#/components/schemas/Media"}},"required":["media"]},"DomainsListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"DomainsAddResponse":{"type":"object","properties":{"domain":{"$ref":"#/components/schemas/Domain"}},"required":["domain"]},"DomainsVerifyResponse":{"type":"object","properties":{"domain":{"$ref":"#/components/schemas/Domain"}},"required":["domain"]},"AgentOpenapiResponse":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"BillingPlansResponse":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"defaultPlan":{"type":"string","pattern":"^[a-z][a-z0-9_]{0,31}$","description":"A plan key from the product's plans.json, e.g. `pro`."}},"required":["plans","defaultPlan"]},"BillingSubscriptionResponse":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/Subscription"}},"required":["subscription"]},"PaymentsAccountResponse":{"type":"object","properties":{"enabled":{"type":"boolean"},"account":{"anyOf":[{"$ref":"#/components/schemas/PaymentsAccount"},{"type":"null"}]}},"required":["enabled","account"]},"PaymentsCreateCustomerResponse":{"type":"object","properties":{"customer":{"$ref":"#/components/schemas/PaymentCustomer"}},"required":["customer"]},"PaymentsGetCustomerResponse":{"type":"object","properties":{"customer":{"$ref":"#/components/schemas/PaymentCustomer"}},"required":["customer"]},"PaymentsCreateResponse":{"type":"object","properties":{"payment":{"$ref":"#/components/schemas/Payment"},"confirmation":{"anyOf":[{"$ref":"#/components/schemas/StripeConfirmation"},{"type":"null"}]}},"required":["payment","confirmation"]},"PaymentsGetResponse":{"type":"object","properties":{"payment":{"$ref":"#/components/schemas/Payment"}},"required":["payment"]},"PaymentsRefundResponse":{"type":"object","properties":{"payment":{"$ref":"#/components/schemas/Payment"},"refund":{"type":"object","properties":{"id":{"type":"string"},"amountMinor":{"type":"integer"},"status":{"type":"string"}},"required":["id","amountMinor","status"]}},"required":["payment","refund"]},"NotesListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Note"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"NotesCreateResponse":{"type":"object","properties":{"note":{"$ref":"#/components/schemas/Note"}},"required":["note"]},"NotesGetResponse":{"type":"object","properties":{"note":{"$ref":"#/components/schemas/Note"}},"required":["note"]},"NotesUpdateResponse":{"type":"object","properties":{"note":{"$ref":"#/components/schemas/Note"}},"required":["note"]},"BookingListLocationsResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Location"}}},"required":["items"]},"BookingCreateLocationResponse":{"type":"object","properties":{"location":{"$ref":"#/components/schemas/Location"}},"required":["location"]},"BookingUpdateLocationResponse":{"type":"object","properties":{"location":{"$ref":"#/components/schemas/Location"}},"required":["location"]},"BookingListServicesResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Service"}}},"required":["items"]},"BookingCreateServiceResponse":{"type":"object","properties":{"service":{"$ref":"#/components/schemas/Service"}},"required":["service"]},"BookingUpdateServiceResponse":{"type":"object","properties":{"service":{"$ref":"#/components/schemas/Service"}},"required":["service"]},"BookingListStaffResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/StaffMember"}}},"required":["items"]},"BookingCreateStaffResponse":{"type":"object","properties":{"staff":{"$ref":"#/components/schemas/StaffMember"}},"required":["staff"]},"BookingUpdateStaffResponse":{"type":"object","properties":{"staff":{"$ref":"#/components/schemas/StaffMember"}},"required":["staff"]},"BookingGetPolicyResponse":{"type":"object","properties":{"policy":{"$ref":"#/components/schemas/BookingPolicy"},"version":{"type":"integer"},"updatedAt":{"anyOf":[{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},{"type":"null"}],"description":"Null while the shop uses the defaults."}},"required":["policy","version","updatedAt"]},"BookingGetStaffHoursResponse":{"type":"object","properties":{"windows":{"type":"array","items":{"$ref":"#/components/schemas/StaffHoursWindow"}}},"required":["windows"]},"BookingGetLocationHoursResponse":{"type":"object","properties":{"windows":{"type":"array","items":{"$ref":"#/components/schemas/HoursWindow"}}},"required":["windows"]},"BookingListTimeOffResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TimeOff"}}},"required":["items"]},"BookingCreateTimeOffResponse":{"type":"object","properties":{"timeOff":{"$ref":"#/components/schemas/TimeOff"}},"required":["timeOff"]},"BookingAvailabilityResponse":{"type":"object","properties":{"slots":{"type":"array","items":{"$ref":"#/components/schemas/Slot"}}},"required":["slots"]},"BookingCreateHoldResponse":{"type":"object","properties":{"hold":{"$ref":"#/components/schemas/Hold"}},"required":["hold"]},"BookingCreateAppointmentResponse":{"type":"object","properties":{"appointment":{"$ref":"#/components/schemas/Appointment"}},"required":["appointment"]},"BookingListAppointmentsResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Appointment"}}},"required":["items"]},"BookingListCustomersResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}}},"required":["items"]},"BookingPublicLocationsResponse":{"type":"object","properties":{"locations":{"type":"array","items":{"$ref":"#/components/schemas/PublicLocation"}}},"required":["locations"]},"BookingPublicServicesResponse":{"type":"object","properties":{"services":{"type":"array","items":{"$ref":"#/components/schemas/PublicService"}},"policy":{"$ref":"#/components/schemas/PublicPolicy"}},"required":["services","policy"]},"BookingPublicStaffResponse":{"type":"object","properties":{"staff":{"type":"array","items":{"$ref":"#/components/schemas/PublicStaffMember"}}},"required":["staff"]},"BookingClientsListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BookingClient"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"]},"BookingClientsGetResponse":{"type":"object","properties":{"client":{"$ref":"#/components/schemas/BookingClient"},"history":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Appointment"}},"nextCursor":{"description":"Pass as `cursor` to get the next page; null on the last page.","type":["string","null"]}},"required":["items","nextCursor"],"description":"Newest-created bookings first, including cancelled bookings."}},"required":["client","history"]},"BookingClientsCreateResponse":{"type":"object","properties":{"client":{"$ref":"#/components/schemas/BookingClient"}},"required":["client"]},"TenantsUpdateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}]},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"locale":{"type":"string","pattern":"^[a-z]{2,3}(-[A-Z][a-z]{3})?(-([A-Z]{2}|\\d{3}))?$","description":"BCP 47 language tag, e.g. en-US."}}},"MediaCreateUploadRequest":{"type":"object","properties":{"contentType":{"type":"string","enum":["image/jpeg","image/png","image/webp","image/gif","application/pdf","video/mp4","video/quicktime"],"description":"File types that can be uploaded. Images (JPEG, PNG, WebP, GIF) up to 10 MB, PDFs up to 25 MB, videos (MP4, MOV) up to 200 MB."},"size":{"type":"integer","minimum":1,"maximum":209715200,"description":"Exact size of the file in bytes."},"filename":{"type":"string","minLength":1,"maxLength":200},"visibility":{"default":"private","type":"string","enum":["public","private"],"description":"`public`: served by the CDN at a permanent URL anyone can open (logos, product photos). `private`: only through short-lived signed links (documents, anything personal)."}},"required":["contentType","size"]},"DomainsAddRequest":{"type":"object","properties":{"host":{"type":"string","minLength":3,"maxLength":253,"pattern":"^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$","description":"A host name, e.g. book.example.com."}},"required":["host"]},"PaymentsCreateCustomerRequest":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"name":{"type":"string","minLength":1,"maxLength":200},"phone":{"type":"string","minLength":3,"maxLength":40},"reference":{"type":"string","minLength":1,"maxLength":200}}},"PaymentsCreateRequest":{"type":"object","properties":{"amountMinor":{"type":"integer","minimum":50,"maximum":99999999,"description":"Amount in minor units (cents)."},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},"customerId":{"type":"string","pattern":"^pcu_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `pcu_` prefix."},"offSession":{"type":"boolean"},"saveCard":{"description":"Keep the card used for this payment on file (needs customerId).","type":"boolean"},"description":{"type":"string","minLength":1,"maxLength":500},"reference":{"type":"string","minLength":1,"maxLength":200}},"required":["amountMinor","currency"]},"PaymentsRefundRequest":{"type":"object","properties":{"amountMinor":{"description":"Default: everything not yet refunded.","type":"integer","minimum":1},"reason":{"type":"string","enum":["duplicate","fraudulent","requested_by_customer"]}}},"NotesCreateRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"body":{"type":"string","maxLength":20000}},"required":["title","body"]},"NotesUpdateRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"body":{"type":"string","maxLength":20000}}},"BookingCreateLocationRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"address":{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"country":{"type":"string","pattern":"^[A-Z]{2}$"}}},"phone":{"anyOf":[{"type":"string","pattern":"^\\+[1-9][0-9]{6,14}$","description":"Phone number in E.164 format, e.g. +17025550100."},{"type":"null"}]},"active":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."}},"required":["name","timezone"]},"BookingUpdateLocationRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","minLength":1,"maxLength":64,"description":"IANA time zone, e.g. America/Los_Angeles."},"address":{"type":"object","properties":{"line1":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"line2":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"city":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"region":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"postalCode":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}]},"country":{"type":"string","pattern":"^[A-Z]{2}$"}}},"phone":{"anyOf":[{"type":"string","pattern":"^\\+[1-9][0-9]{6,14}$","description":"Phone number in E.164 format, e.g. +17025550100."},{"type":"null"}]},"active":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."}}},"BookingCreateServiceRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"durationMinutes":{"type":"integer","minimum":5,"maximum":1440},"bufferBeforeMinutes":{"type":"integer","minimum":0,"maximum":240},"bufferAfterMinutes":{"type":"integer","minimum":0,"maximum":240},"processingGap":{"anyOf":[{"type":"object","properties":{"offsetMinutes":{"type":"integer","minimum":1,"maximum":1435,"description":"Minutes after the start when the gap begins."},"lengthMinutes":{"type":"integer","minimum":1,"maximum":1435}},"required":["offsetMinutes","lengthMinutes"],"description":"A pause inside the service (color developing): the staff member is free, the client is not."},{"type":"null"}]},"price":{"type":"object","properties":{"type":{"type":"string","enum":["fixed","from","range","free","quote"]},"amountMinor":{"type":"integer","minimum":0,"maximum":100000000},"maxAmountMinor":{"type":"integer","minimum":0,"maximum":100000000},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."}},"required":["type"]},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Required deposit in minor units of the service currency (0 = none). This amount alone is not proof of payment."},"active":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."}},"required":["name","durationMinutes","price"]},"BookingUpdateServiceRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"durationMinutes":{"type":"integer","minimum":5,"maximum":1440},"bufferBeforeMinutes":{"type":"integer","minimum":0,"maximum":240},"bufferAfterMinutes":{"type":"integer","minimum":0,"maximum":240},"processingGap":{"anyOf":[{"type":"object","properties":{"offsetMinutes":{"type":"integer","minimum":1,"maximum":1435,"description":"Minutes after the start when the gap begins."},"lengthMinutes":{"type":"integer","minimum":1,"maximum":1435}},"required":["offsetMinutes","lengthMinutes"],"description":"A pause inside the service (color developing): the staff member is free, the client is not."},{"type":"null"}]},"price":{"type":"object","properties":{"type":{"type":"string","enum":["fixed","from","range","free","quote"]},"amountMinor":{"type":"integer","minimum":0,"maximum":100000000},"maxAmountMinor":{"type":"integer","minimum":0,"maximum":100000000},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."}},"required":["type"]},"depositMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Required deposit in minor units of the service currency (0 = none). This amount alone is not proof of payment."},"active":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."}}},"BookingCreateStaffRequest":{"type":"object","properties":{"displayName":{"type":"string","minLength":1,"maxLength":120},"title":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"bio":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"bookable":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."},"membershipId":{"anyOf":[{"type":"string","pattern":"^mem_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `mem_` prefix."},{"type":"null"}]},"serviceIds":{"description":"Replaces the services this person performs.","maxItems":500,"type":"array","items":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}}},"required":["displayName"]},"BookingUpdateStaffRequest":{"type":"object","properties":{"displayName":{"type":"string","minLength":1,"maxLength":120},"title":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}]},"bio":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"bookable":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":-1000000,"maximum":1000000,"description":"Display order, lowest first."},"membershipId":{"anyOf":[{"type":"string","pattern":"^mem_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `mem_` prefix."},{"type":"null"}]},"serviceIds":{"description":"Replaces the services this person performs.","maxItems":500,"type":"array","items":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."}}}},"BookingUpdatePolicyRequest":{"type":"object","properties":{"minNoticeMinutes":{"type":"integer","minimum":0,"maximum":43200,"description":"Online bookings start at least this long from now."},"maxAdvanceDays":{"type":"integer","minimum":1,"maximum":730,"description":"…and at most this many days ahead."},"slotIntervalMinutes":{"type":"integer","minimum":5,"maximum":240,"description":"Start times are offered on this grid from local midnight."},"holdMinutes":{"type":"integer","minimum":2,"maximum":60,"description":"How long a hold keeps a time while the client checks out."},"cancellationWindowHours":{"type":"integer","minimum":0,"maximum":720,"description":"A client cancelling later than this before the start is a late cancellation."},"rescheduleWindowHours":{"type":"integer","minimum":0,"maximum":720,"description":"Clients may move a booking until this long before it."},"reminderOffsetsMinutes":{"maxItems":3,"type":"array","items":{"type":"integer","minimum":5,"maximum":20160}},"currency":{"type":"string","pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code."},"lateCancelFeeMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Stored only: fees are not charged yet."},"noShowFeeMinor":{"type":"integer","minimum":0,"maximum":100000000,"description":"Stored only: fees are not charged yet."},"allowAnyStaff":{"type":"boolean","description":"Clients may pick \"any staff member\"."},"staffCanSeeClientContact":{"type":"boolean","description":"Staff see their clients' email and phone on their schedule."},"policyText":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"description":"Shown to clients before they book."}}},"BookingSetStaffHoursRequest":{"type":"object","properties":{"windows":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"locationId":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"weekday":{"type":"integer","minimum":1,"maximum":7,"description":"ISO weekday: 1 = Monday … 7 = Sunday."},"startMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Minutes after local midnight (540 = 9:00, 1440 = the end of the day)."},"endMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Exclusive; 1440 = until midnight."}},"required":["locationId","weekday","startMinute","endMinute"]},"description":"Replaces every weekly window of this person (one person cannot be in two places: no overlaps)."}},"required":["windows"]},"BookingSetLocationHoursRequest":{"type":"object","properties":{"windows":{"maxItems":100,"type":"array","items":{"type":"object","properties":{"weekday":{"type":"integer","minimum":1,"maximum":7,"description":"ISO weekday: 1 = Monday … 7 = Sunday."},"startMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Minutes after local midnight (540 = 9:00, 1440 = the end of the day)."},"endMinute":{"type":"integer","minimum":0,"maximum":1440,"description":"Exclusive; 1440 = until midnight."}},"required":["weekday","startMinute","endMinute"]},"description":"Replaces the opening hours. Empty: no restriction."}},"required":["windows"]},"BookingCreateTimeOffRequest":{"type":"object","properties":{"staffId":{"type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `stf_` prefix."},"locationId":{"type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `loc_` prefix."},"startDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date YYYY-MM-DD, read in the location's time zone."},"endDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Calendar date YYYY-MM-DD, read in the location's time zone."},"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"endsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"reason":{"type":"string","maxLength":200}}},"BookingCreateHoldRequest":{"type":"object","properties":{"serviceId":{"type":"string","pattern":"^svc_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `svc_` prefix."},"staffId":{"description":"Omit to let the shop assign someone (the least booked that day).","type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$"},"locationId":{"description":"Required when the shop has more than one location.","type":"string","pattern":"^loc_[0-7][0-9a-hjkmnp-tv-z]{25}$"},"startsAt":{"type":"string","format":"date-time","description":"One of the slots from availability."},"ignoreSchedule":{"description":"Allow a time outside weekly hours or during time off (audited). Overlaps are still refused.","type":"boolean"}},"required":["serviceId","startsAt"]},"BookingCreateAppointmentRequest":{"type":"object","properties":{"holdId":{"type":"string","pattern":"^hld_[0-7][0-9a-hjkmnp-tv-z]{25}$","description":"Id with the `hld_` prefix."},"customerId":{"description":"An existing client…","type":"string","pattern":"^cus_[0-7][0-9a-hjkmnp-tv-z]{25}$"},"customer":{"description":"…or a new or returning one by email or phone.","type":"object","properties":{"givenName":{"type":"string","minLength":1,"maxLength":100},"familyName":{"type":"string","maxLength":100},"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"phone":{"type":"string","pattern":"^\\+[1-9][0-9]{6,14}$","description":"Phone number in E.164 format, e.g. +17025550100."}},"required":["givenName"]},"customerNote":{"type":"string","maxLength":1000},"internalNote":{"type":"string","maxLength":4000},"notifyCustomer":{"description":"Email the confirmation and reminders (default true).","type":"boolean"}},"required":["holdId"]},"BookingRescheduleAppointmentRequest":{"type":"object","properties":{"startsAt":{"type":"string","format":"date-time","description":"ISO-8601 instant in UTC."},"staffId":{"description":"Move to another staff member who performs the service.","type":"string","pattern":"^stf_[0-7][0-9a-hjkmnp-tv-z]{25}$"},"expectedVersion":{"description":"Fail with VERSION_CONFLICT if the appointment changed.","type":"integer","minimum":1},"ignoreSchedule":{"description":"Book outside weekly hours or time off (audited). Overlaps are still refused.","type":"boolean"},"notifyCustomer":{"type":"boolean"}},"required":["startsAt"]},"BookingCancelAppointmentRequest":{"type":"object","properties":{"by":{"description":"Who asked (default business).","type":"string","enum":["customer","business"]},"reason":{"type":"string","maxLength":500},"expectedVersion":{"type":"integer","minimum":1},"notifyCustomer":{"type":"boolean"}}},"BookingClientsCreateRequest":{"type":"object","properties":{"givenName":{"type":"string","minLength":1,"maxLength":100},"familyName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"email":{"anyOf":[{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","pattern":"^\\+[1-9][0-9]{6,14}$","description":"Phone number in E.164 format, e.g. +17025550100."},{"type":"null"}]},"notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]}},"required":["givenName"],"additionalProperties":false},"BookingClientsUpdateRequest":{"type":"object","properties":{"givenName":{"type":"string","minLength":1,"maxLength":100},"familyName":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"email":{"anyOf":[{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},{"type":"null"}]},"phone":{"anyOf":[{"type":"string","pattern":"^\\+[1-9][0-9]{6,14}$","description":"Phone number in E.164 format, e.g. +17025550100."},{"type":"null"}]},"notes":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}]},"expectedVersion":{"type":"integer","minimum":1}},"required":["expectedVersion"],"additionalProperties":false}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"A session access token (JWT) or an API key (`ak_…`)."}}},"x-permissions":[{"name":"tenant.manage","description":"Change the tenant's name, time zone and locale.","module":"platform"},{"name":"tenant.delete","description":"Delete the tenant (reserved for the owner).","module":"platform"},{"name":"members.view","description":"See members and pending invites.","module":"platform"},{"name":"members.manage","description":"Invite people, change roles and permissions, remove members.","module":"platform"},{"name":"integrations.manage","description":"Create and revoke API keys and agent keys.","module":"platform"},{"name":"audit.view","description":"Read the audit log.","module":"platform"},{"name":"billing.subscribe","description":"Start a paid plan for the tenant (Stripe Checkout).","module":"platform"},{"name":"billing.manage","description":"Manage the tenant's subscription: change plan, payment method and invoices, or cancel (owners).","module":"platform"},{"name":"payments.manage","description":"Set up the tenant's payments account (Stripe) and see its status and payouts.","module":"platform"},{"name":"payments.charge","description":"Take payments from the tenant's customers and keep their cards on file.","module":"platform"},{"name":"payments.refund","description":"Refund payments.","module":"platform"},{"name":"media.view","description":"See the workspace's files.","module":"platform"},{"name":"media.manage","description":"Upload and delete files.","module":"platform"},{"name":"settings.manage","description":"Change workspace settings such as custom domains.","module":"platform"},{"name":"notes.view","description":"Read notes.","module":"notes"},{"name":"notes.manage","description":"Create, change and delete notes.","module":"notes"},{"name":"booking.view","description":"See locations, services, staff, hours, time off, policies and every appointment.","module":"booking"},{"name":"booking.setup.manage","description":"Change locations, services, staff, who performs what, and the policy.","module":"booking"},{"name":"booking.schedule.manage","description":"Set weekly hours and time off for any staff member or location.","module":"booking"},{"name":"booking.appointments.manage","description":"Book, move and cancel any appointment.","module":"booking"},{"name":"booking.clients.view","description":"Read and search the shop client directory and booking history.","module":"booking"},{"name":"booking.clients.manage","description":"Create and update client records, subject to contact and private-note permissions.","module":"booking"},{"name":"booking.clients.contact","description":"Read, search and update client email addresses and phone numbers.","module":"booking"},{"name":"booking.clients.notes","description":"Read and update private client notes and read internal appointment notes.","module":"booking"},{"name":"booking.deposits.view","description":"Inspect deposit reservations and outstanding compensation for the shop.","module":"booking"}],"x-roles":[{"name":"owner","description":"Everything, including billing and deleting the tenant.","permissions":["tenant.manage","tenant.delete","members.view","members.manage","integrations.manage","audit.view","billing.subscribe","billing.manage","payments.manage","payments.charge","payments.refund","media.view","media.manage","settings.manage","notes.view","notes.manage","booking.view","booking.setup.manage","booking.schedule.manage","booking.appointments.manage","booking.clients.view","booking.clients.manage","booking.clients.contact","booking.clients.notes","booking.deposits.view"]},{"name":"admin","description":"Everything except managing the subscription and deleting the tenant.","permissions":["tenant.manage","members.view","members.manage","integrations.manage","audit.view","billing.subscribe","payments.manage","payments.charge","payments.refund","media.view","media.manage","settings.manage","notes.view","notes.manage","booking.view","booking.setup.manage","booking.schedule.manage","booking.appointments.manage","booking.clients.view","booking.clients.manage","booking.clients.contact","booking.clients.notes","booking.deposits.view"]},{"name":"manager","description":"Manage the shop calendar, staff schedules and client directory.","permissions":["booking.view","booking.appointments.manage","booking.schedule.manage","booking.clients.view","booking.clients.manage","booking.clients.contact","booking.clients.notes"]},{"name":"front_desk","description":"Read the shop calendar, manage bookings and maintain client records.","permissions":["booking.view","booking.appointments.manage","booking.clients.view","booking.clients.manage","booking.clients.contact","booking.clients.notes"]},{"name":"staff","description":"Read the schedule linked to this membership; no unrelated client directory access.","permissions":[]},{"name":"member","description":"Sees the team and uses the product.","permissions":["members.view","media.view","media.manage","notes.view","notes.manage"]},{"name":"viewer","description":"Reads notes and sees the team; changes nothing.","permissions":["members.view","notes.view"]}]}