{"openapi":"3.1.0","info":{"title":"Talkspresso Partner API","version":"1.0.0","summary":"Book, take payment for and run video sessions with a coach roster from your own platform.","description":"Everything under /partner/v1 authenticates with an organization-bound API key (Authorization: Bearer tsp_...). The organization routes at the end are for the organization's own admin key. Times are ISO 8601 with a zone and answers are in UTC. Money is whole US cents and the currency is USD. Every POST except replay needs an Idempotency-Key header. Errors on /partner/v1 are { error: { code, message } }; organization routes use the older { error: \"text\" } shape. Limits per key: 120 reads a minute, 30 writes a minute, 300 bookings or checkouts a day for at most 150 different buyers; a key's first 24 hours run at one quarter of every limit. Staging is for building: api-staging.talkspresso.com with a sandbox key and PayPal's sandbox. Production keys are issued after go-live. Questions: support@talkspresso.com.","contact":{"name":"Talkspresso partner support","email":"support@talkspresso.com"}},"servers":[{"url":"https://api-staging.talkspresso.com","description":"Staging (sandbox key, no real money)"},{"url":"https://api.talkspresso.com","description":"Production (after go-live)"}],"tags":[{"name":"Catalog","description":"Coaches, services, questions and open times."},{"name":"Bookings","description":"Create, read, cancel and move bookings; the buyer's room link."},{"name":"Checkouts","description":"Hosted checkout for paid sessions."},{"name":"Webhooks","description":"The event feed, endpoints and delivery history."},{"name":"Organization","description":"Your organization's settings, branding and roster."},{"name":"Developer kit","description":"This specification."},{"name":"Internal","description":"Called by Talkspresso's own hosted pages. Not for partner servers."}],"security":[{"partnerApiKey":[]}],"paths":{"/partner/v1/openapi.json":{"get":{"operationId":"getOpenApiDocument","summary":"This document","description":"The OpenAPI 3.1 description of the partner API. No key needed. Cached for an hour.","tags":["Developer kit"],"security":[],"responses":{"200":{"description":"The OpenAPI document.","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"The partner API is switched off for this environment.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]}}}},"/partner/v1/providers":{"get":{"operationId":"listProviders","summary":"List your coaches and their bookable services","description":"The organization's approved coaches who agreed to be listed, with their active one-on-one services. A paid service appears only when a buyer could actually pay for it. Group sessions, webinars, request-only and pay-what-you-can services are not listed.","tags":["Catalog"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","responses":{"200":{"description":"The coaches.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Provider"}}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/settings":{"get":{"operationId":"getSettings","summary":"Your organization's settings and go-live checklist","description":"Read only. The checklist tells your developers what is open and who unblocks it. Never gated by readiness, so you can always read why you are not ready.","tags":["Organization"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","responses":{"200":{"description":"Settings and checklist.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PartnerSettings"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/services/{serviceId}/intake-questions":{"get":{"operationId":"getIntakeQuestions","summary":"The booking questions for a service","tags":["Catalog"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"serviceId","in":"path","required":true,"description":"A service id from GET /providers.","schema":{"type":"string"}}],"responses":{"200":{"description":"The questions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/IntakeQuestions"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"422":{"description":"The service cannot be booked through the partner API (a group session, request-only or pay-what-you-can).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["service_not_supported"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/services/{serviceId}/availability":{"get":{"operationId":"getAvailability","summary":"Open times for a service","description":"Always fresh: never cached, so a slot a booking just took is gone. At most 14 days per call.","tags":["Catalog"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"serviceId","in":"path","required":true,"description":"A service id from GET /providers.","schema":{"type":"string"}},{"name":"from","in":"query","required":true,"description":"First day, YYYY-MM-DD.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"days","in":"query","required":false,"description":"How many days, 1 to 14.","schema":{"type":"integer","minimum":1,"maximum":14,"default":7}},{"name":"timezone","in":"query","required":false,"description":"IANA timezone the slots are grouped in.","schema":{"type":"string","maxLength":64,"default":"UTC"}}],"responses":{"200":{"description":"The slots.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Availability"}},"required":["data"]}}}},"400":{"description":"A query value is missing or wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"422":{"description":"The service cannot be booked through the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["service_not_supported"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/bookings":{"post":{"operationId":"createBooking","summary":"Book a free session","description":"Free services only. The buyer is a guest: no Talkspresso account is created. Paid services answer 402 payment_required with next: POST /partner/v1/checkouts.","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:bookings","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required on every POST except replay. 8 to 255 characters: letters, digits and _ . : -. Use a new value for each action. Sending the same value with the same body returns the first answer and adds the response header Idempotent-Replayed: true. The same value with a different body is refused with 422 idempotency_key_reused.","schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[A-Za-z0-9_.:\\-]{8,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBookingRequest"}}}},"responses":{"201":{"description":"The booking, with the buyer's join link.","headers":{"Idempotent-Replayed":{"description":"true when this is the stored answer to an earlier call with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Booking"}},"required":["data"]}}}},"400":{"description":"A field is missing or wrong (fields lists them), or the Idempotency-Key header is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","idempotency_key_required","idempotency_key_invalid"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"402":{"description":"The service is paid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["payment_required"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"409":{"description":"The time is gone, the call is still being processed, or the booking emails setting is not available.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["slot_unavailable","request_in_progress","notifications_mode_not_enabled","webhook_endpoint_required"]},"422":{"description":"The request is understood but cannot be done.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["buyer_email_not_usable","booking_terms_need_buyer_consent","service_not_supported","idempotency_key_reused"]},"429":{"description":"A rate or daily limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited","daily_limit_reached","daily_buyer_limit_reached"]}}},"get":{"operationId":"listBookings","summary":"List the bookings your platform created","description":"Newest first. Only bookings made through your partner keys appear; no list row carries a join link.","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"from","in":"query","required":false,"description":"Bookings starting at or after this time.","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"description":"Bookings starting before this time.","schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","required":false,"description":"Filter by status.","schema":{"type":"string","enum":["active","cancelled","awaiting_payment","completed"]}},{"name":"provider_id","in":"query","required":false,"description":"Filter by coach.","schema":{"type":"string","maxLength":100}},{"name":"partner_ref","in":"query","required":false,"description":"Filter by your own reference.","schema":{"type":"string","maxLength":128}},{"name":"cursor","in":"query","required":false,"description":"next_cursor from the previous page.","schema":{"type":"string","maxLength":300}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"A page of bookings.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BookingListRow"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]}}}},"400":{"description":"A query value is wrong, or the cursor is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","invalid_cursor"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/bookings/{id}":{"get":{"operationId":"getBooking","summary":"One booking, with the buyer's join link","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"id","in":"path","required":true,"description":"A booking id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The booking.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Booking"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/bookings/{id}/intake":{"get":{"operationId":"getBookingIntake","summary":"The buyer's answers to the booking questions","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"id","in":"path","required":true,"description":"A booking id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The answers.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/BookingIntake"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/bookings/{id}/room-links":{"get":{"operationId":"getRoomLinks","summary":"The buyer's video room link, for your own page","description":"Buyer only, for bookings your platform created, each issue is audited. Needs the video setting iframe and an allowed site registered for your organization. Never cached. 60 an hour.","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"id","in":"path","required":true,"description":"A booking id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The room link.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RoomLink"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"409":{"description":"There is no room to show right now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["booking_cancelled","not_a_video_booking","room_unavailable","session_over","video_mode_not_enabled","no_allowed_origins"]},"429":{"description":"Too many room links this hour.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["room_link_rate_limited","rate_limited"]}}}},"/partner/v1/bookings/{id}/cancel":{"post":{"operationId":"cancelBooking","summary":"Cancel a booking with a full refund","description":"Always a full refund and never the buyer's late fee, so a reason_code is required. The coach must have agreed that your platform may cancel their sessions. Cancelling a booking that is already cancelled is a harmless repeat. 20 an hour.","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:bookings","parameters":[{"name":"id","in":"path","required":true,"description":"A booking id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required on every POST except replay. 8 to 255 characters: letters, digits and _ . : -. Use a new value for each action. Sending the same value with the same body returns the first answer and adds the response header Idempotent-Replayed: true. The same value with a different body is refused with 422 idempotency_key_reused.","schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[A-Za-z0-9_.:\\-]{8,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRequest"}}}},"responses":{"200":{"description":"The cancelled booking.","headers":{"Idempotent-Replayed":{"description":"true when this is the stored answer to an earlier call with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Booking"}},"required":["data"]}}}},"400":{"description":"A field is missing or wrong (fields lists them), or the Idempotency-Key header is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","idempotency_key_required","idempotency_key_invalid"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"409":{"description":"The coach has not agreed, or the call is still being processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["coach_consent_required","request_in_progress"]},"422":{"description":"The same Idempotency-Key was used with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["idempotency_key_reused"]},"429":{"description":"Too many cancels this hour.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["cancel_rate_limited","rate_limited"]}}}},"/partner/v1/bookings/{id}/reschedule":{"post":{"operationId":"rescheduleBooking","summary":"Move a booking to another open time","description":"The new time must be exactly a slot the coach offers, and the booking's own reschedule rules apply. The coach must have agreed that your platform may move their sessions. A move inside the fee window is refused 409 reschedule_fee_required: only the buyer can pay that fee, from the link in their booking email. 20 an hour.","tags":["Bookings"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:bookings","parameters":[{"name":"id","in":"path","required":true,"description":"A booking id.","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required on every POST except replay. 8 to 255 characters: letters, digits and _ . : -. Use a new value for each action. Sending the same value with the same body returns the first answer and adds the response header Idempotent-Replayed: true. The same value with a different body is refused with 422 idempotency_key_reused.","schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[A-Za-z0-9_.:\\-]{8,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RescheduleRequest"}}}},"responses":{"200":{"description":"The moved booking.","headers":{"Idempotent-Replayed":{"description":"true when this is the stored answer to an earlier call with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Booking"}},"required":["data"]}}}},"400":{"description":"A field is missing or wrong (fields lists them), or the Idempotency-Key header is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","idempotency_key_required","idempotency_key_invalid"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"409":{"description":"The coach has not agreed, the time is gone, a fee applies, or the call is still being processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["coach_consent_required","slot_unavailable","reschedule_fee_required","request_in_progress"]},"422":{"description":"The same Idempotency-Key was used with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["idempotency_key_reused"]},"429":{"description":"Too many moves this hour.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["reschedule_rate_limited","rate_limited"]}}}},"/partner/v1/checkouts":{"post":{"operationId":"createCheckout","summary":"Open a hosted checkout for a paid session","description":"Talkspresso holds the slot request and the buyer pays on our hosted page; your server never touches the payment. Send the buyer to data.url. The checkout lasts 30 minutes. At most 5 checkouts a minute for one buyer email.","tags":["Checkouts"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:bookings","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required on every POST except replay. 8 to 255 characters: letters, digits and _ . : -. Use a new value for each action. Sending the same value with the same body returns the first answer and adds the response header Idempotent-Replayed: true. The same value with a different body is refused with 422 idempotency_key_reused.","schema":{"type":"string","minLength":8,"maxLength":255,"pattern":"^[A-Za-z0-9_.:\\-]{8,255}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutRequest"}}}},"responses":{"201":{"description":"The checkout, with the hosted page address.","headers":{"Idempotent-Replayed":{"description":"true when this is the stored answer to an earlier call with the same Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Checkout"}},"required":["data"]}}}},"400":{"description":"A field is missing or wrong (fields lists them), or the Idempotency-Key header is missing or malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","idempotency_key_required","idempotency_key_invalid"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"409":{"description":"The time is gone, the money setup is not ready, or the call is still being processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["slot_unavailable","channel_fee_unset","org_owner_not_ready","org_payee_mismatch","provider_not_connected","request_in_progress","notifications_mode_not_enabled","webhook_endpoint_required"]},"422":{"description":"The request is understood but cannot be done.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["service_is_free","buyer_email_not_usable","return_url_not_allowed","service_not_supported","idempotency_key_reused"]},"429":{"description":"A rate or daily limit was reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited","daily_limit_reached","daily_buyer_limit_reached"]}}}},"/partner/v1/checkouts/{id}":{"get":{"operationId":"getCheckout","summary":"The state of a checkout","description":"Poll this or listen for the checkout.paid webhook. Never returns the hosted page address.","tags":["Checkouts"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"id","in":"path","required":true,"description":"A checkout id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The checkout.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Checkout"}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/events":{"get":{"operationId":"listEvents","summary":"The event feed, oldest first, for catching up","description":"Pass the last id you processed as since. Events appear about 30 seconds after they happen.","tags":["Webhooks"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"since","in":"query","required":false,"description":"Return events after this event id.","schema":{"type":"string","pattern":"^evt_[0-9a-f]{24}$"}},{"name":"type","in":"query","required":false,"description":"Only this event type.","schema":{"type":"string","enum":["booking.created","booking.paid","booking.cancelled","booking.rescheduled","booking.completed","checkout.paid","checkout.expired","occurrence.sold_out","ping"]}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"A page of events.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}},"required":["data","has_more","next_cursor"]}}}},"400":{"description":"A query value is wrong, the type is unknown, or since is not an id of yours.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed","invalid_cursor"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/events/{id}/replay":{"post":{"operationId":"replayEvent","summary":"Ask for an event to be sent to your endpoints again","description":"Re-sends the stored payload to every active endpoint that takes this event type. At most 5 an hour per event. No Idempotency-Key needed.","tags":["Webhooks"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:webhooks","parameters":[{"name":"id","in":"path","required":true,"description":"An event id, evt_ followed by 24 hex characters.","schema":{"type":"string"}}],"responses":{"200":{"description":"How many deliveries were queued.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"event_id":{"type":"string"},"queued_deliveries":{"type":"integer"}},"required":["event_id","queued_deliveries"]}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"410":{"description":"The event is older than the 90 day retention window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["event_expired"]},"429":{"description":"Too many replays of this event this hour.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["replay_rate_limited","rate_limited"]}}}},"/partner/v1/webhook-endpoints":{"get":{"operationId":"listWebhookEndpoints","summary":"Where your events are sent","description":"Read only. There is no call to create, change or delete an endpoint or a secret.","tags":["Webhooks"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","responses":{"200":{"description":"The endpoints.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}},"required":["data"]}}}},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner/v1/webhook-deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"Delivery attempts, newest first","tags":["Webhooks"],"security":[{"partnerApiKey":[]}],"x-scope":"partner:read","parameters":[{"name":"endpoint_id","in":"query","required":false,"description":"Only this endpoint.","schema":{"type":"string","maxLength":64}},{"name":"event_id","in":"query","required":false,"description":"Only this event.","schema":{"type":"string","maxLength":64}},{"name":"status","in":"query","required":false,"description":"Only this status.","schema":{"type":"string","enum":["pending","delivered","abandoned"]}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"The deliveries.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}}},"required":["data"]}}}},"400":{"description":"A query value is wrong.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["validation_failed"]},"401":{"description":"No key, a wrong key, an expired key or a revoked key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_credentials"]},"403":{"description":"The key lacks the scope, or the organization is not ready to use the partner API.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["missing_scope","org_not_ready","org_not_supported","owner_not_admin","key_misconfigured"]},"404":{"description":"The partner API is switched off for this environment, or the id does not exist, belongs to another organization, or was not created by your platform.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["not_found"]},"429":{"description":"Too many calls. retry_after_seconds says how long to wait (also sent as a Retry-After header).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["rate_limited"]}}}},"/partner-checkout/{id}/resolve":{"post":{"operationId":"hostedCheckoutResolve","summary":"Hosted checkout page: load the checkout (internal)","description":"Called by the Talkspresso hosted checkout page in the buyer's browser. No key: the signed token in the body is the credential. Not for partner servers. 30 a minute per IP.","tags":["Internal"],"x-internal":true,"security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"A checkout id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostedResolveRequest"}}}},"responses":{"200":{"description":"The buyer-facing summary: first name and a masked email only.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HostedResolveResponse"}},"required":["data"]}}}},"403":{"description":"The link is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_checkout_link"]}}}},"/partner-checkout/{id}/return":{"post":{"operationId":"hostedCheckoutReturn","summary":"Hosted checkout page: where to send the buyer after paying (internal)","description":"Called by the hosted checkout page. Returns the return address re-checked against your organization's current allowed hosts. Not for partner servers. 30 a minute per IP.","tags":["Internal"],"x-internal":true,"security":[],"parameters":[{"name":"id","in":"path","required":true,"description":"A checkout id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostedResolveRequest"}}}},"responses":{"200":{"description":"The redirect address, or null.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HostedReturnResponse"}},"required":["data"]}}}},"403":{"description":"The link is not valid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerError"}}},"x-error-codes":["invalid_checkout_link"]}}}},"/organization/my":{"get":{"tags":["Organization"],"operationId":"listMyOrganizations","summary":"The organizations the key's owner belongs to","security":[{"partnerApiKey":[]}],"x-scope":"read","responses":{"200":{"description":"The organizations, with userRole and adminRole on each.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}":{"get":{"tags":["Organization"],"operationId":"getOrganization","summary":"One organization (what a key may read)","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The organization.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Organization"}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}},"put":{"tags":["Organization"],"operationId":"updateOrganizationPut","summary":"Change the organization's branding and copy","description":"Same as PATCH. Owners and admins only; a manager is refused. Branding and copy only, see OrganizationUpdate.","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUpdate"}}}},"responses":{"200":{"description":"The updated organization.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Organization"}},"required":["data"]}}}},"400":{"description":"A field a key may not write (field_not_allowed_for_keys) or a bad value (invalid_field_value). Nothing is saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}},"patch":{"tags":["Organization"],"operationId":"updateOrganization","summary":"Change the organization's branding and copy","description":"Owners and admins only; a manager is refused. Branding and copy only, see OrganizationUpdate.","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUpdate"}}}},"responses":{"200":{"description":"The updated organization.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Organization"}},"required":["data"]}}}},"400":{"description":"A field a key may not write (field_not_allowed_for_keys) or a bad value (invalid_field_value). Nothing is saved.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/members":{"get":{"tags":["Organization"],"operationId":"listOrganizationMembers","summary":"The organization's members","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}},{"name":"status","in":"query","required":false,"description":"Filter by membership status.","schema":{"type":"string"}},{"name":"featured","in":"query","required":false,"description":"Filter by featured.","schema":{"type":"string","enum":["true","false"]}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The members.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationMember"}},"total":{"type":"integer"}},"required":["members","total"]}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/members/{memberId}":{"put":{"tags":["Organization"],"operationId":"updateOrganizationMemberPut","summary":"Change a member's title, bio, featured flag or order","description":"Same as PATCH.","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}},{"name":"memberId","in":"path","required":true,"description":"The membership id, not the user id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdate"}}}},"responses":{"200":{"description":"The updated member.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OrganizationMember"}},"required":["data"]}}}},"400":{"description":"A field a key may not write, such as status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}},"patch":{"tags":["Organization"],"operationId":"updateOrganizationMember","summary":"Change a member's title, bio, featured flag or order","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}},{"name":"memberId","in":"path","required":true,"description":"The membership id, not the user id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdate"}}}},"responses":{"200":{"description":"The updated member.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/OrganizationMember"}},"required":["data"]}}}},"400":{"description":"A field a key may not write, such as status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}},"delete":{"tags":["Organization"],"operationId":"removeOrganizationMember","summary":"Remove a member from the organization","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}},{"name":"memberId","in":"path","required":true,"description":"The membership id, not the user id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Removed.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/invitations":{"post":{"tags":["Organization"],"operationId":"createOrganizationInvitation","summary":"Invite a coach to the organization","description":"Creates the invitation and returns it, including the join token. The API call itself does not send an email. The coach signs in, reads and accepts the partner consent, and is then listed. A key may send at most 20 invitations a day.","security":[{"partnerApiKey":[]}],"x-scope":"org:write","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationRequest"}}}},"responses":{"200":{"description":"The invitation.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Invitation"}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/stats":{"get":{"tags":["Organization"],"operationId":"getOrganizationStats","summary":"Member and revenue totals","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Totals.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/activity":{"get":{"tags":["Organization"],"operationId":"getOrganizationActivity","summary":"Sessions across the organization","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Rows and totals.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/activity/overview":{"get":{"tags":["Organization"],"operationId":"getOrganizationActivityOverview","summary":"What needs attention and what is coming up","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The overview.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/reporting/summary":{"get":{"tags":["Organization"],"operationId":"getOrganizationReportingSummary","summary":"Gross, fees and shares for a period","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The summary, in cents.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/payouts":{"get":{"tags":["Organization"],"operationId":"listOrganizationPayouts","summary":"Payout history","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"The payouts.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/commissions/pending":{"get":{"tags":["Organization"],"operationId":"listOrganizationPendingCommissions","summary":"Commissions not yet paid out","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Page size.","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"Rows to skip.","schema":{"type":"integer"}}],"responses":{"200":{"description":"The pending commissions.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":true}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}},"/organization/{id}/partner-settings":{"get":{"tags":["Organization"],"operationId":"getOrganizationPartnerSettings","summary":"The same settings and checklist as GET /partner/v1/settings","description":"Read only for a key. Every write method on this path is refused to keys: settings are changed by a person signed in, or by Talkspresso.","security":[{"partnerApiKey":[]}],"x-scope":"read","parameters":[{"name":"id","in":"path","required":true,"description":"The organization id.","schema":{"type":"string"}}],"responses":{"200":{"description":"Settings and checklist.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PartnerSettings"}},"required":["data"]}}}},"401":{"description":"No key or a bad key (body {\"error\":\"...\"}), or a validation failure inside an organization handler, which also arrives as 401 with the reason in error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"403":{"description":"The key lacks the scope, the route is never available to keys, or the key's owner is not an admin of this organization.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}},"404":{"description":"Not found. Activity and reporting reads answer a non-admin with 404.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationError"}}}}}}}},"components":{"securitySchemes":{"partnerApiKey":{"type":"http","scheme":"bearer","bearerFormat":"tsp_<48 hex characters>","description":"Send Authorization: Bearer tsp_... on every call. Keep the key on your server. One key belongs to one organization. Each operation lists the scope it needs in x-scope: partner:read, partner:bookings, partner:webhooks for /partner/v1, and read or org:write for the organization routes."}},"schemas":{"PartnerError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"A stable machine-readable code. Branch on this, not on the message."},"message":{"type":"string","description":"A plain-words explanation. Never contains internal detail."},"fields":{"type":"array","items":{"type":"string"},"description":"validation_failed and some 422s: the request fields at fault."},"retry_after_seconds":{"type":"integer","description":"429 only."},"reason":{"type":"string","description":"slot_unavailable and service_not_supported: why."},"fee_cents":{"type":"integer","description":"reschedule_fee_required only: the fee the buyer would pay."},"currency":{"type":"string","description":"reschedule_fee_required only."},"next":{"type":"string","description":"payment_required only: the call to make instead."},"allowed_types":{"type":"array","items":{"type":"string"},"description":"validation_failed on an unknown event type: the accepted types."},"opens_at":{"type":"string","description":"Present on some refusals that clear at a known time."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"OrganizationError":{"type":"object","properties":{"error":{"description":"Organization routes use the older shape: a string reason, not the partner envelope.","type":"string"},"message":{"type":"string","description":"Present on field_not_allowed_for_keys and invalid_field_value."},"code":{"type":"string","description":"Present on some refusals, for example org_not_found."},"fields":{"type":"array","items":{"type":"string"},"description":"field_not_allowed_for_keys and invalid_field_value: the body fields at fault."}},"required":["error"],"description":"Not the partner envelope. A refusal inside an organization handler can also arrive as 401 with the reason in error (for example a missing email on an invitation); read the text."},"Booking":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"One of active, cancelled, awaiting_payment, completed (the values GET /bookings accepts as a filter)."},"approval_status":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"duration_minutes":{"type":["integer","null"]},"provider":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},"service":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":["string","null"]}},"required":["id","title"]},"buyer":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["name","email"]},"partner_ref":{"type":["string","null"]},"paid_cents":{"type":"integer","description":"Whole US cents."},"currency":{"type":"string","description":"Always USD.","enum":["USD"]},"created_at":{"type":["string","null"],"format":"date-time"},"join_url":{"type":["string","null"],"description":"The buyer's join link. A bearer link: keep it out of logs. Present only on the create response and GET /bookings/{id}, for bookings your platform created, and null for an in-person service."},"notes_available":{"type":"boolean","description":"Always false: notes are never returned."}},"required":["id","status","start_time","end_time","provider","service","buyer","paid_cents","currency","notes_available"]},"BookingListRow":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"approval_status":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"duration_minutes":{"type":["integer","null"]},"provider":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},"service":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":["string","null"]}},"required":["id","title"]},"buyer":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["name","email"]},"partner_ref":{"type":["string","null"]},"paid_cents":{"type":"integer","description":"Whole US cents."},"currency":{"type":"string","enum":["USD"]},"created_at":{"type":["string","null"],"format":"date-time"},"notes_available":{"type":"boolean","description":"Always false."}},"required":["id","status","start_time","end_time","provider","service","buyer","paid_cents","currency","notes_available"],"description":"A booking in a list. Never carries join_url."},"CreateBookingRequest":{"type":"object","properties":{"provider_id":{"type":"string","description":"The coach's id from GET /providers.","maxLength":100},"service_id":{"type":"string","description":"A service id from GET /providers.","maxLength":100},"start_time":{"type":"string","description":"ISO 8601 with an explicit zone offset or Z, for example 2026-11-17T16:00:00Z. A time with no zone is refused. It must be exactly a slot from GET /services/{serviceId}/availability.","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})$"},"buyer":{"type":"object","properties":{"name":{"type":"string","description":"1 to 200 characters.","minLength":1,"maxLength":200},"email":{"type":"string","description":"A usable email address, up to 254 characters.","format":"email","maxLength":254},"phone":{"type":["string","null"],"description":"Up to 50 characters.","maxLength":50},"timezone":{"type":"string","description":"IANA timezone name, for example America/Chicago. Up to 64 characters."}},"required":["name","email"]},"notes":{"type":["string","null"],"description":"Up to 2000 characters.","maxLength":2000},"intake_answers":{"type":"array","items":{"type":"object","properties":{"question_id":{"type":"string","description":"An id from GET /services/{serviceId}/intake-questions.","maxLength":100},"answer":{"oneOf":[{"type":"string","maxLength":5000},{"type":"array","items":{"type":"string","maxLength":5000},"maxItems":20}]}},"required":["question_id","answer"]},"maxItems":50},"partner_ref":{"type":["string","null"],"description":"Your own order or user reference, up to 128 characters. Comes back on the booking, in webhooks and in GET /bookings?partner_ref=.","maxLength":128},"notifications":{"type":"string","description":"Who sends this buyer's booking emails. Absent means the organization's setting. A value the organization is not set up for is refused with 409 notifications_mode_not_enabled.","enum":["talkspresso","branded","partner"]}},"required":["provider_id","service_id","start_time","buyer"],"additionalProperties":false,"description":"Free services only. A paid service answers 402 payment_required: open a checkout instead."},"CreateCheckoutRequest":{"type":"object","properties":{"provider_id":{"type":"string","description":"The coach's id from GET /providers.","maxLength":100},"service_id":{"type":"string","description":"A service id from GET /providers.","maxLength":100},"start_time":{"type":"string","description":"ISO 8601 with an explicit zone offset or Z, for example 2026-11-17T16:00:00Z. A time with no zone is refused. It must be exactly a slot from GET /services/{serviceId}/availability.","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})$"},"buyer":{"type":"object","properties":{"name":{"type":"string","description":"1 to 200 characters.","minLength":1,"maxLength":200},"email":{"type":"string","description":"A usable email address, up to 254 characters.","format":"email","maxLength":254},"phone":{"type":["string","null"],"description":"Up to 50 characters.","maxLength":50},"timezone":{"type":"string","description":"IANA timezone name, for example America/Chicago. Up to 64 characters."}},"required":["name","email"]},"notes":{"type":["string","null"],"description":"Up to 2000 characters.","maxLength":2000},"intake_answers":{"type":"array","items":{"type":"object","properties":{"question_id":{"type":"string","description":"An id from GET /services/{serviceId}/intake-questions.","maxLength":100},"answer":{"oneOf":[{"type":"string","maxLength":5000},{"type":"array","items":{"type":"string","maxLength":5000},"maxItems":20}]}},"required":["question_id","answer"]},"maxItems":50},"partner_ref":{"type":["string","null"],"description":"Your own order or user reference, up to 128 characters. Comes back on the booking, in webhooks and in GET /bookings?partner_ref=.","maxLength":128},"notifications":{"type":"string","description":"Who sends this buyer's booking emails. Absent means the organization's setting. A value the organization is not set up for is refused with 409 notifications_mode_not_enabled.","enum":["talkspresso","branded","partner"]},"return_url":{"type":"string","description":"Where the buyer is sent after paying. https only, on a host registered for your organization (else 422 return_url_not_allowed). Up to 2048 characters.","maxLength":2048}},"required":["provider_id","service_id","start_time","buyer"],"additionalProperties":false,"description":"Paid services only. A free service answers 422 service_is_free: use POST /bookings."},"CancelRequest":{"type":"object","properties":{"reason_code":{"type":"string","description":"Required. Why the booking is cancelled. It is stored with the key id, and the buyer's email gives it in plain words.","enum":["buyer_requested","partner_cause","duplicate","fraud_suspected"]},"reason":{"type":["string","null"],"description":"Free text for your own records, up to 1000 characters. Never shown to the buyer.","maxLength":1000}},"required":["reason_code"],"additionalProperties":false},"RescheduleRequest":{"type":"object","properties":{"start_time":{"type":"string","description":"The new start, ISO 8601 with a zone. Must be exactly a slot the coach offers.","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d+)?)?(Z|[+-]\\d{2}:\\d{2})$"}},"required":["start_time"],"additionalProperties":false},"Checkout":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","description":"open, paid, expired or cancelled. A status=paid hint on the return redirect can be edited by the buyer: confirm with this call or the checkout.paid webhook.","enum":["open","paid","expired","cancelled"]},"url":{"type":"string","description":"The hosted checkout page for the buyer. Present only on the create response. Carries a signed token: treat it as a secret, send the buyer to it, do not log it."},"expires_at":{"type":"string","format":"date-time"},"partner_ref":{"type":["string","null"]},"booking_id":{"type":["string","null"],"description":"Set once the checkout is paid and the booking exists."},"provider_id":{"type":"string"},"service_id":{"type":"string"},"start_time":{"type":"string","format":"date-time"}},"required":["id","status","expires_at","provider_id","service_id","start_time"]},"Provider":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"title":{"type":["string","null"],"description":"The member title the organization gave the coach."},"handle":{"type":["string","null"]},"photo_url":{"type":["string","null"]},"headline":{"type":["string","null"]},"services":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"duration_minutes":{"type":"integer"},"price_cents":{"type":"integer","description":"Whole US cents."},"currency":{"type":"string","enum":["USD"]},"free":{"type":"boolean"}},"required":["id","title","duration_minutes","price_cents","currency","free"]}}},"required":["id","name","services"],"description":"A coach the organization has listed. Only approved, consented coaches with bookable one-on-one services appear."},"Availability":{"type":"object","properties":{"service_id":{"type":"string"},"provider_id":{"type":"string"},"timezone":{"type":"string","description":"The timezone you asked for."},"duration_minutes":{"type":"integer"},"slots":{"type":"array","items":{"type":"object","properties":{"start_time":{"type":"string","description":"ISO 8601."},"end_time":{"type":"string","description":"ISO 8601."}},"required":["start_time","end_time"]}}},"required":["service_id","provider_id","timezone","duration_minutes","slots"]},"IntakeQuestion":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"},"questionType":{"type":"string"},"options":{"description":"Choices for a choice question, otherwise null.","type":["array","null"],"items":{}},"isRequired":{"type":"boolean"},"placeholder":{"type":["string","null"]},"helperText":{"type":["string","null"]}},"required":["id","question","isRequired"]},"IntakeQuestions":{"type":"object","properties":{"service_id":{"type":"string"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/IntakeQuestion"}},"requires_heard_about_us":{"type":"boolean","description":"true when the coach requires a 'how did you hear about us' answer."}},"required":["service_id","questions","requires_heard_about_us"]},"BookingIntake":{"type":"object","properties":{"booking_id":{"type":"string"},"answers":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}},"required":["question","answer"]}}},"required":["booking_id","answers"]},"RoomLink":{"type":"object","properties":{"booking_id":{"type":"string"},"role":{"type":"string","enum":["buyer"]},"url":{"type":"string","description":"The buyer's room link. A bearer link: keep it out of logs."},"embed_url":{"type":"string","description":"The same link with embed=1, for an iframe on one of parent_origins."},"parent_origins":{"type":"array","items":{"type":"string"},"description":"The origins registered for your organization that may frame the room."},"session_ends_at":{"type":["string","null"],"format":"date-time"}},"required":["booking_id","role","url","embed_url","parent_origins","session_ends_at"]},"BookingObject":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["booking"]},"status":{"type":["string","null"]},"approval_status":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"end_time":{"type":["string","null"],"format":"date-time"},"duration_minutes":{"type":["integer","null"]},"provider":{"type":"object","properties":{"id":{"type":["string","null"]},"name":{"type":["string","null"]}}},"service":{"type":"object","properties":{"id":{"type":["string","null"]},"title":{"type":["string","null"]}}},"buyer":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]}}},"partner_ref":{"type":["string","null"]},"paid_cents":{"type":"integer"},"currency":{"type":"string","enum":["USD"]},"session_outcome":{"type":["string","null"]},"cancelled_by":{"type":["string","null"],"description":"buyer, coach, partner, system or unknown. Only when status is cancelled."},"updated_at":{"type":["string","null"],"description":"Drop an event whose updated_at is older than the one you already hold.","format":"date-time"}},"required":["id","object","status","approval_status","start_time","end_time","duration_minutes","provider","service","buyer","partner_ref","paid_cents","currency","session_outcome","cancelled_by","occurrence_id","updated_at"],"description":"The booking inside a webhook or event. Never carries a join link, manage link, notes or intake answers: fetch GET /bookings/{id} for those."},"CheckoutObject":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","enum":["checkout"]},"status":{"type":"string"},"partner_ref":{"type":["string","null"]},"booking_id":{"type":["string","null"]},"provider_id":{"type":["string","null"]},"service_id":{"type":["string","null"]},"start_time":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}},"required":["id","object","status","partner_ref","booking_id","provider_id","service_id","start_time","expires_at","updated_at"]},"Event":{"type":"object","properties":{"id":{"type":"string","description":"evt_ followed by 24 hex characters."},"type":{"type":"string","enum":["booking.created","booking.paid","booking.cancelled","booking.rescheduled","booking.completed","checkout.paid","checkout.expired","occurrence.sold_out","ping"]},"api_version":{"type":"string","enum":["2026-11-12"]},"created":{"type":"string","format":"date-time"},"organization_id":{"type":"string"},"data":{"type":"object","properties":{"object":{"oneOf":[{"$ref":"#/components/schemas/BookingObject"},{"$ref":"#/components/schemas/CheckoutObject"}],"description":"A ping event carries an empty object."}},"required":["object"]}},"required":["id","type","api_version","created","organization_id","data"],"description":"The same body your endpoint receives, signed there with the Talkspresso-Signature header (t=<unix seconds>,v1=<hex>). Events appear in this feed about 30 seconds after they happen. Payloads are kept for 90 days."},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"},"description":"Empty means every event type."},"status":{"type":"string"},"disabled_reason":{"type":["string","null"]},"consecutive_failures":{"type":"integer"},"last_success_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"}},"required":["id","url","events","status","consecutive_failures","created_at"],"description":"Read only. Endpoints and secrets are created and changed by Talkspresso on request; no key can do it."},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"string"},"event_id":{"type":"string"},"endpoint_id":{"type":"string"},"status":{"type":"string","enum":["pending","delivered","abandoned"]},"attempts":{"type":"integer"},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"last_status_code":{"type":["integer","null"]},"last_error_class":{"type":["string","null"]},"duration_ms":{"type":["integer","null"]},"delivered_at":{"type":["string","null"],"format":"date-time"},"replays":{"type":"integer"},"created_at":{"type":["string","null"],"format":"date-time"}},"required":["id","event_id","endpoint_id","status","attempts","replays"]},"PartnerSettings":{"type":"object","properties":{"partner_access":{"type":"boolean"},"viewer_can_edit":{"type":"boolean","description":"Always false for a key."},"settings":{"type":"object","properties":{"surface":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: headless, subdomain."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"listing":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: invite_only, approval."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"money":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: coach_direct."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"buyer":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: guest."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"notifications":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: talkspresso, branded, partner."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"video":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: page, iframe."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"data":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: partner_created."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]},"compliance":{"type":"object","properties":{"value":{"type":"string","description":"What is set. Built values: adults_only."},"effective":{"type":"string","description":"What actually happens today."},"source":{"type":"string","enum":["default","set"]},"set_by":{"type":"string","description":"you or talkspresso."},"editable_by_you":{"type":"boolean"},"options":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"available":{"type":"boolean"},"reason":{"type":["string","null"]}},"required":["value","available"]}}},"required":["value","effective","source","set_by","editable_by_you","options"]}},"required":["surface","listing","money","buyer","notifications","video","data","compliance"],"description":"One entry per switch: surface, listing, money, buyer, notifications, video, data, compliance."},"channel_fee":{"type":"object","properties":{"percent":{"type":["number","null"]},"set_by":{"type":"string"}}},"lists":{"type":"object","properties":{"return_hosts":{"type":"array","items":{"type":"string"}},"allowed_sites":{"type":"array","items":{"type":"string"}}}},"identity":{"type":"object","properties":{"contact_email_set":{"type":"boolean"},"support_email_set":{"type":"boolean"}}},"clearances":{"type":"object","properties":{},"additionalProperties":{"type":"boolean"},"description":"Which agreement and test clearances stand, by name. No dates or references."},"checklist":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"item":{"type":"string"},"status":{"type":"string","description":"done, todo, blocked or not_applicable."},"why":{"type":"string","description":"Plain words: what is open and what unblocks it."},"who":{"type":"string","description":"Who does it: talkspresso, org_admin or partner."},"gate":{"type":"string","description":"key (needed for a key) or live (needed to go live)."}},"required":["id","item","status","why","who","gate"]}},"summary":{"type":"object","properties":{"ready_for_key":{"type":"boolean"},"ready_to_go_live":{"type":"boolean"},"sandbox":{"type":"boolean"},"open_items":{"type":"integer"},"blocked_items":{"type":"integer"}},"required":["ready_for_key","ready_to_go_live","sandbox","open_items","blocked_items"]}},"required":["items","summary"]},"last_changes":{"type":"object","properties":{},"additionalProperties":{"type":"object","properties":{"at":{"type":"string","format":"date-time"},"by":{"type":"string","description":"A role label such as Owner or Admin, or Talkspresso. Never a person's name."}},"required":["at","by"]}},"is_partner":{"type":"boolean"}},"required":["settings","checklist"],"description":"Never contains secrets, payee ids, clearance dates or a person's name."},"Organization":{"type":"object","properties":{"id":{},"name":{},"slug":{},"custom_domain":{},"logo_url":{},"icon_url":{},"favicon_url":{},"primary_color":{},"secondary_color":{},"accent_color":{},"tagline":{},"description":{},"hero_image_url":{},"hero_title":{},"hero_subtitle":{},"member_term_singular":{},"member_term_plural":{},"session_term":{},"session_term_plural":{},"locale":{},"is_active":{"type":"boolean"},"is_public":{"type":"boolean"},"require_member_approval":{"type":"boolean"},"allow_member_applications":{"type":"boolean"},"default_category":{},"show_free_label":{"type":"boolean"},"payments_enabled":{"type":"boolean"},"noindex":{"type":"boolean"},"website_url":{},"social_links":{"type":"object","properties":{},"additionalProperties":{"type":"string"}},"total_members":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"description":"What a key may read of an organization. Fees, rates, payee, secrets and contact emails are never returned to a key. Fields not typed here come back as strings or null."},"OrganizationUpdate":{"type":"object","properties":{"logo_url":{"type":["string","null"],"description":"https URL, up to 255 characters. null clears it."},"icon_url":{"type":["string","null"],"description":"https URL, up to 255 characters. null clears it."},"primary_color":{"type":["string","null"],"description":"#rrggbb. null clears it.","pattern":"^#[0-9a-fA-F]{6}$"},"secondary_color":{"type":["string","null"],"description":"#rrggbb. null clears it.","pattern":"^#[0-9a-fA-F]{6}$"},"accent_color":{"type":["string","null"],"description":"#rrggbb. null clears it.","pattern":"^#[0-9a-fA-F]{6}$"},"tagline":{"type":["string","null"],"description":"null clears it."},"description":{"type":["string","null"],"description":"null clears it."},"hero_image_url":{"type":["string","null"],"description":"https URL, up to 255 characters. null clears it."},"hero_title":{"type":["string","null"],"description":"null clears it."},"hero_subtitle":{"type":["string","null"],"description":"null clears it."},"member_term_singular":{"type":["string","null"],"description":"null clears it."},"member_term_plural":{"type":["string","null"],"description":"null clears it."},"session_term":{"type":["string","null"],"description":"null clears it."},"session_term_plural":{"type":["string","null"],"description":"null clears it."},"website_url":{"type":["string","null"],"description":"https URL, up to 255 characters. null clears it."},"social_links":{"type":"object","properties":{"twitter":{"type":"string","description":"https URL."},"linkedin":{"type":"string","description":"https URL."},"instagram":{"type":"string","description":"https URL."},"facebook":{"type":"string","description":"https URL."},"youtube":{"type":"string","description":"https URL."},"tiktok":{"type":"string","description":"https URL."}},"additionalProperties":false,"description":"At most 10 entries."},"default_category":{"type":["string","null"],"description":"null clears it."}},"additionalProperties":false,"description":"Branding and copy only. Any other field (name, slug, locale, is_active, payments_enabled, revenue_share_percent, contact emails and so on) is refused with 400 field_not_allowed_for_keys, naming the fields; nothing is saved. Text limits: tagline 160, description 2000, hero_title 160, hero_subtitle 400, the four term fields 40, default_category 80."},"OrganizationMember":{"type":"object","properties":{"id":{"type":"string","description":"The membership id. Not the user id."},"organization_id":{"type":"string"},"user_id":{"type":"string"},"membership_type":{"type":"string"},"is_featured":{"type":"boolean"},"sort_order":{"type":"integer"},"member_title":{"type":["string","null"]},"member_bio":{"type":["string","null"]},"hide_price":{"type":"boolean"},"status":{"type":"string"},"total_sessions":{"type":"integer"},"user":{"type":"object","description":"The member's user record (public fields)."},"roster":{"type":"object"}},"required":["id","organization_id","user_id","status"],"additionalProperties":true},"MemberUpdate":{"type":"object","properties":{"member_title":{"type":["string","null"]},"member_bio":{"type":["string","null"]},"is_featured":{"type":"boolean"},"sort_order":{"type":"integer"}},"additionalProperties":false,"description":"A key may not change status (approve or suspend a member): that is refused with 400 field_not_allowed_for_keys."},"InvitationRequest":{"type":"object","properties":{"email":{"type":"string","description":"Required. A valid email address.","format":"email"},"name":{"type":"string"},"member_title":{"type":"string"}},"required":["email"]},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"organization_id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"member_title":{"type":["string","null"]},"status":{"type":"string"},"invite_token":{"type":"string","description":"A bearer join link token: treat it as a secret."}},"required":["id","organization_id","email"],"additionalProperties":true,"description":"Creating an invitation through the API does not send an email. A key sends at most 20 invitations a day."},"HostedResolveRequest":{"type":"object","properties":{"token":{"type":"string","description":"The signed checkout token from the hosted checkout URL."}},"required":["token"]},"HostedResolveResponse":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"organization":{"type":"object","properties":{"name":{"type":["string","null"]},"logo_url":{"type":["string","null"]},"primary_color":{"type":["string","null"]}}},"provider":{"type":"object","properties":{"name":{"type":["string","null"]},"handle":{"type":["string","null"]},"photo_url":{"type":["string","null"]}}},"service":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":["string","null"]},"duration_minutes":{"type":"integer"},"price_cents":{"type":"integer"},"currency":{"type":"string"}}},"slot_start":{"type":"string","format":"date-time"},"buyer":{"type":"object","properties":{"first_name":{"type":["string","null"]},"email_masked":{"type":"string"}}},"has_return_url":{"type":"boolean"}},"required":["id","status"]},"HostedReturnResponse":{"type":"object","properties":{"redirect_url":{"type":["string","null"],"description":"Where to send the buyer, or null when there is no valid return address."},"status":{"type":"string","enum":["paid","cancelled"]}},"required":["status"]}}}}