{"openapi":"3.1.0","info":{"title":"topcal API","version":"0.1.0","description":"Agent-native scheduling. Every operation is reachable via REST (this spec) and via MCP (`/api/mcp`). Both surfaces share the same Zod schemas, so a tool that works in one works in the other.\n\nBrowse interactive docs at `/docs`. All errors use a stable envelope: `{ error: { code, message, details? } }`."},"servers":[{"url":"https://topcal.app/api/v1","description":"v1"}],"security":[{"ApiKey":[]}],"components":{"securitySchemes":{"ApiKey":{"type":"http","scheme":"bearer","bearerFormat":"topcal-api-key","description":"Workspace API key. Format: `tofu_live_<32-char-secret>`."},"AgentIntent":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Delegated JWT bound to a verified `agent_principal`. Required for any endpoint that performs an action on behalf of a verified human."}},"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","description":"Stable machine-readable error code"},"message":{"type":"string","description":"Human-readable error message"},"details":{}},"required":["code","message"]}},"required":["error"]},"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"name":{"type":"string","enum":["topcal"]},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"transports":{"type":"object","properties":{"rest":{"type":"string","description":"Path to the REST API"},"mcp":{"type":"string","description":"Path to the Model Context Protocol endpoint"},"openapi":{"type":"string","description":"Path to the OpenAPI 3.1 spec JSON"}},"required":["rest","mcp","openapi"]}},"required":["status","name","version","timestamp","transports"]},"RegisterAgentIdentityResponse":{"type":"object","properties":{"principalId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending"]},"verificationExpiresAt":{"type":"string","format":"date-time"},"instructions":{"type":"string"}},"required":["principalId","status","verificationExpiresAt","instructions"]},"RegisterAgentIdentityRequest":{"type":"object","properties":{"prospectEmail":{"type":"string","format":"email"},"prospectName":{"type":"string","minLength":1,"maxLength":120},"prospectCompany":{"type":"string","minLength":1,"maxLength":120},"agentLabel":{"type":"string","minLength":1,"maxLength":160},"metadata":{"type":"object","additionalProperties":{}}},"required":["prospectEmail","agentLabel"]},"VerifyAgentIdentityResponse":{"type":"object","properties":{"principalId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["verified"]},"intentToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"scopes":{"type":"array","items":{"type":"string","enum":["agent.identity.read","agent.identity.revoke","agent.user.signup","agent.workspace.create","agent.workspace.invite","agent.billing.checkout","agent.booking.read","agent.booking.write","agent.calendar.connect"]}}},"required":["principalId","status","intentToken","expiresAt","scopes"]},"VerifyAgentIdentityRequest":{"type":"object","properties":{"code":{"type":"string","pattern":"^\\d{6}$"},"scopes":{"type":"array","items":{"type":"string","enum":["agent.identity.read","agent.identity.revoke","agent.user.signup","agent.workspace.create","agent.workspace.invite","agent.billing.checkout","agent.booking.read","agent.booking.write","agent.calendar.connect"]},"minItems":1,"maxItems":9}},"required":["code","scopes"]},"RevokeAgentIdentityResponse":{"type":"object","properties":{"principalId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["revoked"]},"revokedAt":{"type":"string","format":"date-time"}},"required":["principalId","status","revokedAt"]},"SignupAgentUserResponse":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","email","name","createdAt"]},"workspaces":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","manager","member","billing_only"]}},"required":["id","slug","name","role"]}},"created":{"type":"boolean"},"claimAccountUrl":{"type":"string","format":"uri"}},"required":["user","workspaces","created","claimAccountUrl"]},"SignupAgentUserRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","minLength":1,"maxLength":80}}},"AgentConnectCalendarResponse":{"type":"object","properties":{"installUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"targetUser":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"}},"required":["id","email"]},"instructions":{"type":"string"}},"required":["installUrl","expiresAt","targetUser","instructions"]},"AgentConnectCalendarRequest":{"type":"object","properties":{"provider":{"type":"string","enum":["google","microsoft"]},"redirectAfter":{"type":"string","maxLength":512,"pattern":"^\\/"}},"required":["provider"]},"StartCheckoutResponse":{"type":"object","properties":{"intentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending"]},"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"plan":{"type":"string","enum":["solo"]},"interval":{"type":"string","enum":["monthly","annual"]},"quantity":{"type":"integer","minimum":1}},"required":["intentId","status","url","expiresAt","plan","interval","quantity"]},"StartCheckoutRequest":{"type":"object","properties":{"plan":{"type":"string","enum":["solo"]},"interval":{"type":"string","enum":["monthly","annual"],"default":"monthly"},"quantity":{"type":"integer","minimum":1,"maximum":20,"default":1},"customerEmail":{"type":"string","format":"email"},"successUrl":{"type":"string","format":"uri"},"cancelUrl":{"type":"string","format":"uri"},"metadata":{"type":"object","additionalProperties":{"type":"string"}}},"required":["plan"]},"CheckoutIntentResponse":{"type":"object","properties":{"intentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","completed","expired","canceled"]},"requestedPriceId":{"type":"string"},"completedAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"sessionId":{"type":"string"}},"required":["intentId","status","requestedPriceId","completedAt","expiresAt","sessionId"]},"StartEnrichmentCheckoutResponse":{"type":"object","properties":{"intentId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending"]},"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"catalogId":{"type":"string","enum":["enrichment_starter","enrichment_growth","enrichment_scale","enrichment_pack_50","enrichment_pack_200","enrichment_pack_500"]}},"required":["intentId","status","url","expiresAt","catalogId"]},"StartEnrichmentCheckoutRequest":{"type":"object","properties":{"catalogId":{"type":"string","enum":["enrichment_starter","enrichment_growth","enrichment_scale","enrichment_pack_50","enrichment_pack_200","enrichment_pack_500"]},"customerEmail":{"type":"string","format":"email"},"successUrl":{"type":"string","format":"uri"},"cancelUrl":{"type":"string","format":"uri"},"metadata":{"type":"object","additionalProperties":{"type":"string"}}},"required":["catalogId"]},"AgentCreateBookingResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventTypeId":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["pending_confirmation","confirmed","canceled","rescheduled","no_show","completed"]},"joinUrl":{"type":"string","format":"uri"},"htmlLink":{"type":"string","format":"uri"}},"required":["id","eventTypeId","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"]},"AgentCreateBookingRequest":{"type":"object","properties":{"eventTypeId":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"invitee":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","minLength":1,"maxLength":80}},"required":["email","timezone"]},"customFields":{"type":"object","additionalProperties":{}},"idempotencyKey":{"type":"string","minLength":8,"maxLength":128}},"required":["eventTypeId","startAt","invitee"]},"BookingDetailResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"timezone":{"type":"string"},"locationType":{"type":"string"},"source":{"type":"string"},"joinUrl":{"type":["string","null"]},"eventType":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"slug":{"type":["string","null"]}},"required":["id","name","slug"]},"invitee":{"type":"object","properties":{"name":{"type":["string","null"]},"email":{"type":["string","null"]},"timezone":{"type":["string","null"]}},"required":["name","email","timezone"]},"hostNotes":{"type":["string","null"]},"formAnswers":{"type":"array","items":{"$ref":"#/components/schemas/BookingFormAnswerEntry"}},"formAnswersByKey":{"type":"object","additionalProperties":{}}},"required":["id","startAt","endAt","status","timezone","locationType","source","joinUrl","eventType","invitee","hostNotes","formAnswers","formAnswersByKey"]},"BookingFormAnswerEntry":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"value":{}},"required":["key","label"]},"BookingEnrichmentResponse":{"type":"object","properties":{"bookingId":{"type":"string","format":"uuid"},"status":{"type":"string"},"emailClass":{"type":["string","null"]},"domain":{"type":["string","null"]},"creditsCharged":{"type":"integer"},"companyFacts":{"type":["object","null"],"additionalProperties":{}},"personFacts":{"type":["object","null"],"additionalProperties":{}},"conversationSignals":{"type":["object","null"],"additionalProperties":{}},"brief":{"type":["object","null"],"additionalProperties":{}},"score":{"type":["object","null"],"additionalProperties":{}},"providerBreakdown":{"type":["object","null"],"additionalProperties":{}},"error":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["bookingId","status","emailClass","domain","creditsCharged","companyFacts","personFacts","conversationSignals","brief","score","providerBreakdown","error","createdAt","updatedAt"]},"AgentRescheduleResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"joinUrl":{"type":"string","format":"uri"},"htmlLink":{"type":"string","format":"uri"}},"required":["id","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"]},"AgentRescheduleRequest":{"type":"object","properties":{"startAt":{"type":"string","format":"date-time","description":"New slot start, ISO 8601 UTC"}},"required":["startAt"]},"AgentCancelResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"}},"required":["id","status"]},"message":{"type":"string"}},"required":["booking","message"]},"AgentCancelRequest":{"type":"object","properties":{"reason":{"type":"string","maxLength":500}}},"AgentProposeSlotsResponse":{"type":"object","properties":{"eventTypeId":{"type":"string","format":"uuid"},"slots":{"type":"array","items":{"type":"object","properties":{"startUtc":{"type":"string","format":"date-time"},"endUtc":{"type":"string","format":"date-time"}},"required":["startUtc","endUtc"]}},"count":{"type":"integer"}},"required":["eventTypeId","slots","count"]},"AgentProposeSlotsRequest":{"type":"object","properties":{"eventTypeId":{"type":"string","format":"uuid"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"limit":{"type":"integer","minimum":1,"maximum":50,"default":8}},"required":["eventTypeId"]},"PublicEventTypesResponse":{"type":"object","properties":{"calendar":{"type":"object","properties":{"organization":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"owner":{"type":"object","properties":{"username":{"type":"string"}},"required":["username"]},"hostTimezone":{"type":["string","null"]}},"required":["organization","owner","hostTimezone"]},"invitee":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable identifier. Pass answers keyed by this exact value."},"type":{"type":"string","description":"Field input type (e.g. short_text, single_select, boolean)."},"label":{"type":"string","description":"Human-facing question label."},"required":{"type":"boolean","description":"Whether an answer is required when the field is visible."},"helpText":{"type":"string","description":"Guidance for the answerer. Doubles as the agent-facing field description."},"config":{"description":"Type-specific config (e.g. `options` for selects)."},"conditionalLogic":{"description":"When present, the field is only required if these prior answers match."}},"required":["key","type","label","required"]},"description":"Always collect these on GET .../otp (as query params). Custom intake lives in `eventType.form`."}},"required":["fields"]},"eventTypes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"durationMinutes":{"type":"integer"},"locationType":{"type":"string"},"maxFutureDays":{"type":"integer"},"form":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"definition":{"$ref":"#/components/schemas/FormDefinition"},"requiredFieldKeys":{"type":"array","items":{"type":"string"}}},"required":["id","definition","requiredFieldKeys"]}},"required":["id","slug","name","description","durationMinutes","locationType","maxFutureDays","form"]}}},"required":["calendar","invitee","eventTypes"]},"FormDefinition":{"type":["object","null"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable identifier. Pass answers keyed by this exact value."},"type":{"type":"string","description":"Field input type (e.g. short_text, single_select, boolean)."},"label":{"type":"string","description":"Human-facing question label."},"required":{"type":"boolean","description":"Whether an answer is required when the field is visible."},"helpText":{"type":"string","description":"Guidance for the answerer. Doubles as the agent-facing field description."},"config":{"description":"Type-specific config (e.g. `options` for selects)."},"conditionalLogic":{"description":"When present, the field is only required if these prior answers match."}},"required":["key","type","label","required"]}}},"required":["slug","name","fields"]},"PublicSlotsResponse":{"type":"object","properties":{"calendar":{"type":"object","properties":{"organization":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"}},"required":["slug","name"]},"owner":{"type":"object","properties":{"username":{"type":"string"}},"required":["username"]},"hostTimezone":{"type":["string","null"],"description":"Host IANA timezone — weekly hours live in availability.hostSchedule."}},"required":["organization","owner","hostTimezone"]},"eventType":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"durationMinutes":{"type":"integer"},"locationType":{"type":"string"},"maxFutureDays":{"type":"integer"},"form":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"definition":{"$ref":"#/components/schemas/FormDefinition"},"requiredFieldKeys":{"type":"array","items":{"type":"string"}}},"required":["id","definition","requiredFieldKeys"]}},"required":["id","slug","name","durationMinutes","locationType","maxFutureDays","form"]},"invitee":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable identifier. Pass answers keyed by this exact value."},"type":{"type":"string","description":"Field input type (e.g. short_text, single_select, boolean)."},"label":{"type":"string","description":"Human-facing question label."},"required":{"type":"boolean","description":"Whether an answer is required when the field is visible."},"helpText":{"type":"string","description":"Guidance for the answerer. Doubles as the agent-facing field description."},"config":{"description":"Type-specific config (e.g. `options` for selects)."},"conditionalLogic":{"description":"When present, the field is only required if these prior answers match."}},"required":["key","type","label","required"]},"description":"Always collect these on GET .../otp (as query params). Custom intake lives in `eventType.form`."}},"required":["fields"]},"bookingProtocol":{"type":"object","properties":{"id":{"type":"string","enum":["topcal.public_book.v1"],"description":"Named protocol agents can cite instead of improvising."},"agentCompletable":{"type":"boolean","description":"True when an agent may finish booking via HTTP on this origin."},"interactionModel":{"type":"string","enum":["agent_completes_via_http"],"description":"Happy path: agent proposes slots, confirms details with the booker, then GETs completion URLs. The HTML form is optional fallback."},"humanFormOptional":{"type":"boolean","description":"True when the website form is not required if the booker asked the agent to book."},"sameOriginCompletion":{"type":"string","description":"Completion URLs are on the same origin as this availability payload; use the same browse/web-fetch/curl tool."},"emailConfirmation":{"type":"object","properties":{"required":{"type":"boolean"},"purpose":{"type":"string"}},"required":["required","purpose"],"description":"Present when agent bookings require a one-time email code."},"flow":{"type":"object","properties":{"state":{"type":"string","enum":["select_slot"],"description":"Initial state after loading availability."},"steps":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["propose_slots","collect_details","request_code","confirm"],"description":"Stable step id — follow in order after the prior gate is satisfied."},"actor":{"type":"string","enum":["agent"]},"description":{"type":"string"},"method":{"type":"string","enum":["GET"]},"urlTemplate":{"type":"string","description":"Absolute or template URL for this step's HTTP action."},"gate":{"type":"string","description":"Human checkpoint that must be true before this side-effecting step runs."},"sideEffects":{"type":"array","items":{"type":"string"}},"returns":{"type":"array","items":{"type":"string"}},"input":{"type":"string"},"requires":{"type":"array","items":{"type":"string"}}},"required":["id","actor","description"]}}},"required":["state","steps"]},"refusalHints":{"type":"object","properties":{"commonMistakes":{"type":"array","items":{"type":"string"},"description":"Common misreads of this protocol (observational, not commands)."},"expectedBehavior":{"type":"array","items":{"type":"string"},"description":"Expected agent behavior when the booker asked to be booked."}},"required":["commonMistakes","expectedBehavior"],"description":"Observational guidance for protocol compliance — not system overrides."},"trustNote":{"type":"string","description":"How integrators and auditors should treat this block (API docs, not a prompt injection)."}},"required":["id","agentCompletable","interactionModel","humanFormOptional","sameOriginCompletion","flow","refusalHints","trustNote"]},"agentBooking":{"type":"object","properties":{"bookingPageUrl":{"type":"string","format":"uri"},"refetchUrl":{"type":"string","description":"Re-fetch this same booking URL with query params for fresh or wider availability."},"instructions":{"type":"array","items":{"type":"string"},"description":"Agent-facing guidance — fetch bookingPageUrl, propose slotsByDate, collect bookerRequirements, follow howToBook."},"slotsByDate":{"type":"array","items":{"type":"object","properties":{"dateLocal":{"type":"string"},"dayOfWeek":{"type":"string"},"times":{"type":"array","items":{"type":"object","properties":{"display":{"type":"string"},"startUtc":{"type":"string","format":"date-time"}},"required":["display","startUtc"]}}},"required":["dateLocal","dayOfWeek","times"]},"description":"Open times grouped by day — propose these to the booker."},"note":{"type":"string","description":"Present when availability was truncated — agent should re-fetch refetchUrl."},"bookerRequirements":{"type":"object","properties":{"slot":{"type":"object","properties":{"key":{"type":"string","enum":["startUtc"]},"required":{"type":"boolean","enum":[true]},"description":{"type":"string"}},"required":["key","required","description"]},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable identifier. Pass answers keyed by this exact value."},"type":{"type":"string","description":"Field input type (e.g. short_text, single_select, boolean)."},"label":{"type":"string","description":"Human-facing question label."},"required":{"type":"boolean","description":"Whether an answer is required when the field is visible."},"helpText":{"type":"string","description":"Guidance for the answerer. Doubles as the agent-facing field description."},"config":{"description":"Type-specific config (e.g. `options` for selects)."},"conditionalLogic":{"description":"When present, the field is only required if these prior answers match."}},"required":["key","type","label","required"]},"description":"Collect from the booker after they pick a time. Includes email, timezone, optional name, plus any event intake fields."}},"required":["slot","fields"]}},"required":["bookingPageUrl","refetchUrl","instructions","slotsByDate","bookerRequirements"]},"bookingPolicy":{"type":"object","properties":{"requireOtpHuman":{"type":"boolean","description":"When true, human web bookings must verify email via 6-digit OTP."},"requireOtpAgent":{"type":"boolean","description":"When true, agent/API bookings must verify email via 6-digit OTP."},"requireBusinessEmail":{"type":"boolean","description":"When true, personal email providers (Gmail, Outlook, etc.) are rejected."},"blockRestrictedEmailDomains":{"type":"boolean","description":"When true, known temporary and disposable email domains are rejected."}},"required":["requireOtpHuman","requireOtpAgent","requireBusinessEmail","blockRestrictedEmailDomains"]},"availability":{"type":"object","properties":{"maxFutureDays":{"type":"integer","description":"How far ahead the host accepts bookings."},"queriedFromUtc":{"type":"string","format":"date-time"},"queriedToUtc":{"type":"string","format":"date-time","description":"Upper bound of this query — more slots may exist before this date."},"slotsReturned":{"type":"integer"},"limitApplied":{"type":"integer"},"maxLimit":{"type":"integer"},"truncatedByLimit":{"type":"boolean","description":"True when slotsReturned hit limitApplied — pass a higher limit or narrow from/to."},"bookerTimezone":{"type":"string","description":"IANA timezone used for slots[].bookerLocal (from query or host fallback)."},"bookerTimezoneSource":{"type":"string","enum":["query","host_fallback","utc"]},"hostSchedule":{"type":["object","null"],"properties":{"timezone":{"type":"string"},"weeklyRules":{"type":"array","items":{"type":"object","properties":{"dayOfWeek":{"type":"integer","minimum":0,"maximum":6},"dayName":{"type":"string"},"startTime":{"type":"string","description":"HH:mm in host schedule timezone"},"endTime":{"type":"string"}},"required":["dayOfWeek","dayName","startTime","endTime"]}},"summary":{"type":"string","description":"Human-readable weekly hours, e.g. Mon–Fri · 9:00 AM – 5:00 PM"}},"required":["timezone","weeklyRules","summary"],"description":"Host-configured weekly hours; slots never fall outside these windows."},"firstSlotStartUtc":{"type":["string","null"],"format":"date-time"},"lastSlotStartUtc":{"type":["string","null"],"format":"date-time"},"nextAvailableStartUtc":{"type":["string","null"],"format":"date-time","description":"Same as firstSlotStartUtc when slots are non-empty."},"datesInPayload":{"type":"array","items":{"type":"string"},"description":"Local dates (YYYY-MM-DD, booker timezone) covered by slots[] / slotsByDate."},"fromDate":{"type":["string","null"],"description":"When the query was narrowed with fromDate=YYYY-MM-DD."},"toDate":{"type":["string","null"],"description":"When the query was narrowed with toDate=YYYY-MM-DD."}},"required":["maxFutureDays","queriedFromUtc","queriedToUtc","slotsReturned","limitApplied","maxLimit","truncatedByLimit","bookerTimezone","bookerTimezoneSource","hostSchedule","firstSlotStartUtc","lastSlotStartUtc","nextAvailableStartUtc","datesInPayload","fromDate","toDate"]},"slots":{"type":"array","items":{"type":"object","properties":{"startUtc":{"type":"string","format":"date-time"},"endUtc":{"type":"string","format":"date-time"},"bookerLocal":{"type":"object","properties":{"timezone":{"type":"string"},"dateLocal":{"type":"string","description":"YYYY-MM-DD in booker's timezone"},"dayOfWeek":{"type":"string"},"startLocal":{"type":"string"},"endLocal":{"type":"string"},"display":{"type":"string","description":"Ready-to-show time range for the booker, in their timezone"}},"required":["timezone","dateLocal","dayOfWeek","startLocal","endLocal","display"]}},"required":["startUtc","endUtc","bookerLocal"]}},"emptyReason":{"type":"string","enum":["workspace_locked","no_schedule","no_rules","no_calendar","no_slots"]},"howToBook":{"type":"object","properties":{"steps":{"type":"array","items":{"type":"string"}},"requestCodeUrl":{"type":"string"},"confirmResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"joinUrl":{"type":"string","format":"uri","description":"Video/meeting link when the host uses a virtual location."}},"required":["id","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"],"description":"Shape returned by GET .../confirm on success."}},"required":["steps","requestCodeUrl","confirmResponse"]}},"required":["calendar","eventType","invitee","bookingProtocol","agentBooking","bookingPolicy","availability","slots","howToBook"]},"PublicBookingOtpResponse":{"type":"object","properties":{"status":{"type":"string","enum":["otp_sent"]},"email":{"type":"string","format":"email"},"expiresInMinutes":{"type":"integer"},"codeExpiresInSeconds":{"type":"integer","description":"Seconds until the emailed code expires."},"message":{"type":"string"}},"required":["status","email","expiresInMinutes","codeExpiresInSeconds","message"]},"PublicBookingOtpRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","minLength":1,"maxLength":120}},"required":["email"]},"PublicBookingOtpGetResponse":{"type":"object","properties":{"status":{"type":"string","enum":["otp_sent","confirmation_ready"]},"verificationRequired":{"type":"boolean","description":"When false, GET confirmUrl directly — no emailed code."},"email":{"type":"string","format":"email"},"expiresInMinutes":{"type":"integer"},"codeExpiresInSeconds":{"type":"integer","description":"Seconds until the emailed code expires (0 when verification not required)."},"confirmUrl":{"type":"string"},"next":{"type":"string"}},"required":["status","verificationRequired","email","expiresInMinutes","codeExpiresInSeconds","confirmUrl","next"]},"PublicBookResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"joinUrl":{"type":"string","format":"uri"}},"required":["id","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"]},"PublicBookRequest":{"type":"object","properties":{"startAt":{"type":"string","format":"date-time"},"code":{"type":"string","pattern":"^\\d{6}$"},"invitee":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","minLength":1,"maxLength":120},"timezone":{"type":"string","minLength":1}},"required":["email","timezone"]},"customFields":{"type":"object","additionalProperties":{}},"idempotencyKey":{"type":"string","minLength":8,"maxLength":128}},"required":["startAt","code","invitee"]},"PublicConfirmResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"joinUrl":{"type":"string","format":"uri"}},"required":["id","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"]},"PublicRescheduleResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"startAt":{"type":"string","format":"date-time"},"endAt":{"type":"string","format":"date-time"},"status":{"type":"string"},"joinUrl":{"type":"string","format":"uri"}},"required":["id","startAt","endAt","status"]},"message":{"type":"string"}},"required":["booking","message"]},"PublicRescheduleRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1,"description":"Management token from the booking email"},"startAt":{"type":"string","format":"date-time","description":"New slot start, ISO 8601 UTC"}},"required":["token","startAt"]},"PublicCancelResponse":{"type":"object","properties":{"booking":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"}},"required":["id","status"]},"message":{"type":"string"}},"required":["booking","message"]},"PublicCancelRequest":{"type":"object","properties":{"token":{"type":"string","minLength":1,"description":"Management token from the booking email"},"reason":{"type":"string","maxLength":500}},"required":["token"]},"StripeWebhookAck":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]}},"required":["received"]}},"parameters":{}},"paths":{"/health":{"get":{"operationId":"health","summary":"Liveness probe + transport discovery.","description":"Stable, unauthenticated endpoint agents can hit to confirm the API is up and to discover the REST + MCP + OpenAPI URLs without parsing marketing copy.","tags":["meta"],"security":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/identities":{"post":{"operationId":"agent_register_identity","summary":"Declare a verified-human-on-whose-behalf the agent will act.","description":"Creates a pending `agent_principal` row scoped to the API key's workspace and emails the human a 6-digit OTP. The agent receives a stable `principalId` it can use to poll status and call `verify_agent_identity` once the human shares the code.","tags":["agent","identity"],"security":[{"ApiKey":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterAgentIdentityRequest"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterAgentIdentityResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/identities/{principalId}/verify":{"post":{"operationId":"agent_verify_identity","summary":"Consume the OTP and return a delegated intent token.","description":"Confirms the human's consent for the listed scopes and mints a short-lived JWT bound to the verified principal. The agent uses this token (Authorization: Bearer ...) for any operation that performs an action on behalf of this human (sign up, invite, pay, book).","tags":["agent","identity"],"security":[{"ApiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"principalId","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyAgentIdentityRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyAgentIdentityResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/identities/{principalId}/revoke":{"post":{"operationId":"agent_revoke_identity","summary":"Revoke a verified principal.","description":"Either the agent (via API key) or the human (via support flow) can revoke. Once revoked, all outstanding intent tokens for the principal stop being honored on first use — verifications keep running for audit, but mutations are rejected.","tags":["agent","identity"],"security":[{"ApiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"principalId","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeAgentIdentityResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/users":{"post":{"operationId":"agent_signup_user","summary":"Provision a topcal user account on behalf of the verified human.","description":"Creates a `users` row keyed by the principal's email if one doesn't exist. Auto-accepts any pending workspace invitations addressed to that email and, if the user still has no memberships, creates their personal workspace.\n\nIdempotent on email — calling twice returns the same user row with `created: false` the second time.","tags":["agent","signup"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupAgentUserRequest"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupAgentUserResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/calendars/connect":{"post":{"operationId":"agent_connect_calendar","summary":"Mint a calendar-install URL for the verified human to click.","description":"Returns a single-use, signed install URL the agent can deliver to the human (chat, email, etc.). The OAuth dance happens inside the human's own browser session — the agent never sees the resulting calendar tokens. The connection lands on the `users` row whose email matches the verified principal's `prospectEmail`. Call `agent_signup_user` first if the user doesn't exist yet.\n\nTTL: 15 minutes.","tags":["agent","calendar"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentConnectCalendarRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentConnectCalendarResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/billing/checkout-intents":{"post":{"operationId":"agent_start_checkout","summary":"Start a Stripe Checkout session on behalf of a verified human.","description":"The agent declares which paid plan + interval + seat count the human wants. We create a Stripe Checkout Session pre-bound to the workspace's customer + the verified principal, and return the URL the human visits to complete payment.\n\nThe agent never sees the human's payment method; Stripe owns that page. We mirror the session id locally as `agent_checkout_intents.id` so the agent (or a webhook subscriber) can poll for completion.","tags":["agent","billing"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartCheckoutRequest"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartCheckoutResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/billing/checkout-intents/{intentId}":{"get":{"operationId":"agent_get_checkout_intent","summary":"Poll the status of an agent-initiated Stripe Checkout.","description":"Returns `pending` until Stripe fires `checkout.session.completed` (see `/api/v1/webhooks/stripe`), at which point the row flips to `completed`. Use this in an agent loop to know when to follow up with the next step (e.g. `agent_create_workspace` or `book_on_behalf_of`).","tags":["agent","billing"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"intentId","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutIntentResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/billing/enrichment-checkout-intents":{"post":{"operationId":"agent_start_enrichment_checkout","summary":"Start a Stripe Checkout session for enrichment credits.","description":"The agent declares which enrichment subscription tier or one-time credit pack the human wants. Returns a Stripe Checkout URL for the human to complete payment. Poll completion via GET /agent/billing/checkout-intents/{id}.","tags":["agent","billing","enrichment"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartEnrichmentCheckoutRequest"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartEnrichmentCheckoutResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/bookings":{"post":{"operationId":"agent_create_booking","summary":"Book a meeting on behalf of a verified human.","description":"Creates a real calendar event on the rep's connected calendar (Google Meet or Microsoft Teams auto-generated). The slot is re-validated at booking time to prevent double-booking. Supports idempotency via `idempotencyKey`.\n\nRequires a verified principal (see `agent/identities`) and the `agent.booking.write` scope.","tags":["agent","bookings"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateBookingRequest"}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCreateBookingResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/bookings/{bookingId}":{"get":{"operationId":"agent_get_booking","summary":"Fetch a booking including form answers and host notes.","description":"Returns meeting details, invitee, labeled booking-form answers, keyed answers for agents, and private host notes for a booking in the authenticated workspace. Requires agent.booking.read scope.","tags":["agent","bookings"],"security":[{"ApiKey":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"bookingId","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingDetailResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/bookings/{bookingId}/enrichment":{"get":{"operationId":"agent_get_booking_enrichment","summary":"Fetch AI enrichment results for a booking.","description":"Returns Lead Magic person/company facts, optional Grok signals, prep brief, and lead score for a booking in the authenticated workspace. Requires agent.booking.read scope.","tags":["agent","enrichment"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"bookingId","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookingEnrichmentResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/bookings/{bookingId}/reschedule":{"post":{"operationId":"agent_reschedule_booking","summary":"Reschedule a booking on behalf of a verified human.","description":"Moves an existing booking to a new slot. The slot is re-validated, the calendar event is moved (conference link preserved), and a reschedule email is sent. Requires a verified principal and `agent.booking.write`.","tags":["agent","bookings"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"bookingId","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRescheduleRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRescheduleResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/bookings/{bookingId}/cancel":{"post":{"operationId":"agent_cancel_booking","summary":"Cancel a booking on behalf of a verified human.","description":"Cancels an existing booking: deletes the calendar event and sends a cancellation email. Requires a verified principal and `agent.booking.write`.","tags":["agent","bookings"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"bookingId","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCancelRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentCancelResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/event-types":{"get":{"operationId":"agent_list_event_types","summary":"List bookable event types for the authenticated workspace.","description":"Returns event types the agent can book on behalf of the verified principal. Includes attached form schema (if any) so agents know exactly what customFields to collect. Requires agent.booking.read scope.","tags":["agent","event-types"],"security":[{"ApiKey":[]}],"parameters":[{"schema":{"type":["boolean","null"],"default":false},"required":false,"name":"includeInactive","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"eventTypes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"durationMinutes":{"type":"number"},"locationType":{"type":"string"},"allowAgentBooking":{"type":"boolean"},"isPubliclyListed":{"type":"boolean"},"form":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"definition":{"type":["object","null"],"properties":{"slug":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z0-9-]+$"},"name":{"type":"string","minLength":1,"maxLength":200},"description":{"type":"string","maxLength":2000},"fields":{"type":"array","items":{"allOf":[{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"position":{"type":"integer","minimum":0},"key":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-z][a-z0-9_]*$"},"label":{"type":"string","minLength":1,"maxLength":200},"placeholder":{"type":"string","maxLength":200},"helpText":{"type":"string","maxLength":500},"required":{"type":"boolean","default":false},"conditionalLogic":{"type":"object","properties":{"all":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","minLength":1},"op":{"type":"string","enum":["eq","neq","in","not_in","contains","gte","lte","exists"]},"value":{}},"required":["field","op"]},"minItems":1}},"required":["all"]}},"required":["position","key","label"]},{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["short_text"]},"config":{"type":"object","properties":{"minLength":{"type":"integer","minimum":0},"maxLength":{"type":"integer","exclusiveMinimum":0},"pattern":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["long_text"]},"config":{"type":"object","properties":{"minLength":{"type":"integer","minimum":0},"maxLength":{"type":"integer","exclusiveMinimum":0},"pattern":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["email"]},"config":{"type":"object","properties":{"minLength":{"type":"integer","minimum":0},"maxLength":{"type":"integer","exclusiveMinimum":0},"pattern":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["phone"]},"config":{"type":"object","properties":{"minLength":{"type":"integer","minimum":0},"maxLength":{"type":"integer","exclusiveMinimum":0},"pattern":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["url"]},"config":{"type":"object","properties":{"minLength":{"type":"integer","minimum":0},"maxLength":{"type":"integer","exclusiveMinimum":0},"pattern":{"type":"string"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["number"]},"config":{"type":"object","properties":{"min":{"type":"number"},"max":{"type":"number"},"step":{"type":"number","exclusiveMinimum":0}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["currency_range"]},"config":{"type":"object","properties":{"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"value":{"type":"string","minLength":1}},"required":["label","value"]},"minItems":2},"currency":{"type":"string","default":"USD"}},"required":["options"]}},"required":["type","config"]},{"type":"object","properties":{"type":{"type":"string","enum":["single_select"]},"config":{"type":"object","properties":{"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["label","value"]},"minItems":1},"minSelections":{"type":"integer","minimum":0},"maxSelections":{"type":"integer","exclusiveMinimum":0},"allowOther":{"type":"boolean","default":false}},"required":["options"]}},"required":["type","config"]},{"type":"object","properties":{"type":{"type":"string","enum":["multi_select"]},"config":{"type":"object","properties":{"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["label","value"]},"minItems":1},"minSelections":{"type":"integer","minimum":0},"maxSelections":{"type":"integer","exclusiveMinimum":0},"allowOther":{"type":"boolean","default":false}},"required":["options"]}},"required":["type","config"]},{"type":"object","properties":{"type":{"type":"string","enum":["radio"]},"config":{"type":"object","properties":{"options":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1},"value":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["label","value"]},"minItems":1},"minSelections":{"type":"integer","minimum":0},"maxSelections":{"type":"integer","exclusiveMinimum":0},"allowOther":{"type":"boolean","default":false}},"required":["options"]}},"required":["type","config"]},{"type":"object","properties":{"type":{"type":"string","enum":["scale"]},"config":{"type":"object","properties":{"min":{"type":"integer"},"max":{"type":"integer"},"minLabel":{"type":"string"},"maxLabel":{"type":"string"}},"required":["min","max"]}},"required":["type","config"]},{"type":"object","properties":{"type":{"type":"string","enum":["date"]},"config":{"type":"object","properties":{"minDate":{"type":"string"},"maxDate":{"type":"string"},"format":{"type":"string","default":"yyyy-MM-dd"}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["file"]},"config":{"type":"object","properties":{"maxSizeBytes":{"type":"integer","exclusiveMinimum":0,"default":10485760},"acceptedMimeTypes":{"type":"array","items":{"type":"string"},"default":[]},"multiple":{"type":"boolean","default":false}}}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["boolean"]},"config":{"type":"object","properties":{"checkboxLabel":{"type":"string","maxLength":200},"mustBeTrue":{"type":"boolean"}}}},"required":["type"]}]}]},"minItems":1}},"required":["slug","name","fields"]}},"required":["id","definition"]}},"required":["id","slug","name","description","durationMinutes","locationType","allowAgentBooking","isPubliclyListed","form"]}}},"required":["eventTypes"]}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/slots/propose":{"post":{"operationId":"agent_propose_slots","summary":"Propose bookable slots for an event type.","description":"Returns UTC slot candidates the verified human can book, honoring availability rules, buffers, and busy time on the rep's connected calendar. Empty when no calendar is connected. Call this before POST /agent/bookings — the REST mirror of the MCP tool agent_propose_slots.\n\nRequires a verified principal and the `agent.booking.read` scope.","tags":["agent","bookings"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProposeSlotsRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProposeSlotsResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/agent/availability/blocks":{"get":{"operationId":"agent_list_availability_blocks","summary":"List upcoming time-off blocks for the verified human.","description":"Returns full-day and partial-day availability blocks on the verified human's default schedule. Weekly hours are unchanged. Requires `agent.booking.read`.","tags":["agent","availability"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"parameters":[{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive YYYY-MM-DD lower bound (default: today)."},"required":false,"description":"Inclusive YYYY-MM-DD lower bound (default: today).","name":"fromDate","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive YYYY-MM-DD upper bound."},"required":false,"description":"Inclusive YYYY-MM-DD upper bound.","name":"toDate","in":"query"},{"schema":{"type":["boolean","null"],"default":false},"required":false,"name":"includePast","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"scheduleId":{"type":"string","format":"uuid"},"blocks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["full_day","partial"]},"date":{"type":"string"},"startTime":{"type":["string","null"]},"endTime":{"type":["string","null"]},"reason":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","kind","date","startTime","endTime","reason","createdAt"]}},"count":{"type":"integer"}},"required":["scheduleId","blocks","count"]}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"agent_add_availability_blocks","summary":"Block days or hours on the verified human's schedule.","description":"Creates temporary blocks without changing weekly availability. Omit startTime/endTime for full-day OOO (vacation). Include both for partial blocks (appointments). Example vacation: `{ \"fromDate\": \"2026-07-01\", \"toDate\": \"2026-07-07\", \"reason\": \"Vacation\" }`. Example appointment: `{ \"fromDate\": \"2026-06-20\", \"toDate\": \"2026-06-20\", \"startTime\": \"14:00\", \"endTime\": \"15:00\", \"reason\": \"Dentist\" }`. Requires `agent.booking.write`.","tags":["agent","availability"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"type":"object","properties":{"fromDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"First blocked day (inclusive)."},"toDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Last blocked day (inclusive). Same as fromDate for a single day."},"startTime":{"type":"string","pattern":"^([01]\\d|2[0-3]):([0-5]\\d)(?::([0-5]\\d))?$","description":"Optional local start time (HH:mm). When set, endTime is required and creates partial blocks."},"endTime":{"type":"string","pattern":"^([01]\\d|2[0-3]):([0-5]\\d)(?::([0-5]\\d))?$","description":"Optional local end time (HH:mm). Required when startTime is set."},"reason":{"type":"string","maxLength":120,"description":"Optional label, e.g. \"Vacation\" or \"Dentist\"."}},"required":["fromDate","toDate"]}}}},"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"scheduleId":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["full_day","partial"]},"fromDate":{"type":"string"},"toDate":{"type":"string"},"startTime":{"type":["string","null"]},"endTime":{"type":["string","null"]},"reason":{"type":["string","null"]},"dates":{"type":"array","items":{"type":"string"}},"created":{"type":"integer"},"updated":{"type":"integer"}},"required":["scheduleId","kind","fromDate","toDate","startTime","endTime","reason","dates","created","updated"]}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"agent_remove_availability_blocks","summary":"Remove time-off blocks for a date range.","description":"Deletes blocks created via POST /agent/availability/blocks. Include startTime/endTime to remove partial blocks only. Requires `agent.booking.write`.","tags":["agent","availability"],"security":[{"ApiKey":[]},{"AgentIntent":[]}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"type":"object","properties":{"fromDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"toDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"startTime":{"type":"string","pattern":"^([01]\\d|2[0-3]):([0-5]\\d)(?::([0-5]\\d))?$"},"endTime":{"type":"string","pattern":"^([01]\\d|2[0-3]):([0-5]\\d)(?::([0-5]\\d))?$"}},"required":["fromDate","toDate"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"scheduleId":{"type":"string","format":"uuid"},"fromDate":{"type":"string"},"toDate":{"type":"string"},"startTime":{"type":["string","null"]},"endTime":{"type":["string","null"]},"removed":{"type":"integer"}},"required":["scheduleId","fromDate","toDate","startTime","endTime","removed"]}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}":{"get":{"operationId":"public_list_event_types","summary":"List a calendar owner's publicly bookable event types.","description":"Open, unauthenticated discovery for the booker plane. Returns the event types `{workspace}/{username}` has made public AND agent-bookable, each with its attached form definition so an agent knows exactly which fields to collect before booking. No API key required.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicEventTypesResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/slots":{"get":{"operationId":"public_propose_slots","summary":"Propose available slots for a public event type.","description":"Open, unauthenticated availability for the booker plane. Returns bookable slots for `{workspace}/{username}/{eventSlug}`, honoring the owner's weekly hours (availability.hostSchedule), buffers, and live calendar conflicts. Pass `timezone` with the booker's IANA zone so each slot includes bookerLocal.display — never show raw UTC to humans. Default limit is 50 (max 240). No API key required.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":240,"description":"Max slots to return (default 50, max 240)."},"required":false,"description":"Max slots to return (default 50, max 240).","name":"limit","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Booker's IANA timezone — each slot includes bookerLocal display in this zone. Falls back to host timezone when omitted."},"required":false,"description":"Booker's IANA timezone — each slot includes bookerLocal display in this zone. Falls back to host timezone when omitted.","name":"timezone","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive local start date (YYYY-MM-DD, booker timezone) to narrow availability."},"required":false,"description":"Inclusive local start date (YYYY-MM-DD, booker timezone) to narrow availability.","name":"fromDate","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Inclusive local end date (YYYY-MM-DD, booker timezone) to narrow availability."},"required":false,"description":"Inclusive local end date (YYYY-MM-DD, booker timezone) to narrow availability.","name":"toDate","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicSlotsResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/otp":{"post":{"operationId":"public_request_booking_otp","summary":"Request an email OTP to confirm a public booking.","description":"Step 1 of the open booker-plane booking flow. Emails a 6-digit code to the booker; the agent relays it to POST `.../book`. No API key required. Disposable email addresses are rejected; requests are rate-limited per email.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBookingOtpRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBookingOtpResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"get":{"operationId":"public_request_booking_otp_get","summary":"Request a booking OTP and a confirm URL (GET, web-fetch).","description":"Cold-booker (web_fetch) step 1. Pass the chosen slot + invitee as query params; we email a 6-digit code and return a `confirmUrl`. The agent then GETs `confirmUrl&code=<otp>` once the user reads the code back. The signed intent is embedded in confirmUrl (query param `confirmKey`) — there is no separate bookingToken field, so agent security scanners won't redact it. No API key, no POST required.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"},{"schema":{"type":"string","format":"email"},"required":true,"name":"email","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Chosen slot start, ISO 8601 UTC"},"required":true,"description":"Chosen slot start, ISO 8601 UTC","name":"startAt","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Invitee IANA timezone"},"required":true,"description":"Invitee IANA timezone","name":"timezone","in":"query"},{"schema":{"type":"string","minLength":1,"maxLength":120},"required":false,"name":"name","in":"query"},{"schema":{"type":"string"},"required":false,"name":"fields","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBookingOtpGetResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/book":{"post":{"operationId":"public_confirm_booking","summary":"Confirm a public booking with the email OTP.","description":"Step 2 of the open booker-plane flow. Consumes the OTP from `.../otp` (proving email control) and books the meeting via the shared createBooking path — real calendar event + confirmation email. No API key required.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBookRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBookResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/confirm":{"get":{"operationId":"public_confirm_booking_get","summary":"Confirm a public booking with confirmKey + OTP (GET, web-fetch).","description":"Cold-booker (web_fetch) step 2. Verifies the signed confirmKey (from confirmUrl) and the OTP code, then books via the shared createBooking path (real calendar event + invite). Append `&code=` to the confirmUrl returned by GET .../otp. No API key, no POST required.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"},{"schema":{"type":"string","minLength":1,"description":"Signed intent from confirmUrl (preferred)"},"required":false,"description":"Signed intent from confirmUrl (preferred)","name":"confirmKey","in":"query"},{"schema":{"type":"string","minLength":1,"description":"Deprecated alias for confirmKey — kept for older links"},"required":false,"description":"Deprecated alias for confirmKey — kept for older links","name":"token","in":"query"},{"schema":{"type":"string","pattern":"^\\d{6}$","description":"Required when the host enforces email verification for agent bookings"},"required":false,"description":"Required when the host enforces email verification for agent bookings","name":"code","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicConfirmResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/reschedule":{"post":{"operationId":"public_reschedule_booking","summary":"Reschedule a public booking with a management token.","description":"Moves an existing public booking to a new slot. The signed `token` from the booking's confirmation email authorizes the change (no API key). The calendar event is moved and the conference link preserved.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRescheduleRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicRescheduleResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/public/{workspace}/{username}/{eventSlug}/cancel":{"post":{"operationId":"public_cancel_booking","summary":"Cancel a public booking with a management token.","description":"Cancels an existing public booking. The signed `token` from the booking's confirmation email authorizes the change (no API key). The calendar event is deleted and a cancellation email is sent.","tags":["public","booking"],"security":[],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"workspace","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"username","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"eventSlug","in":"path"}],"requestBody":{"description":"Request body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicCancelRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicCancelResponse"}}}},"400":{"description":"Invalid query, path, or body (`request.invalid`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing/invalid API key or agent intent (`auth.required`, `agent.intent.required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Workspace subscription inactive (`billing.upgrade_required`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Insufficient scope or principal state (`auth.forbidden`, `agent.principal.*`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found (`resource.not_found`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Conflict — slot taken, duplicate, etc. (`resource.conflict`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Semantic validation failed (`request.unprocessable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded (`rate.limited`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Unexpected server error (`internal.unexpected`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Dependency unavailable (`service.unavailable`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/webhooks/stripe":{"post":{"operationId":"stripe_webhook","summary":"Stripe webhook receiver.","description":"Verifies the `Stripe-Signature` header against `STRIPE_WEBHOOK_SECRET` and updates `subscriptions` + `agent_checkout_intents` rows. The request body is the raw Stripe `Event` JSON (do NOT pre-parse).","tags":["billing","webhooks"],"security":[],"parameters":[{"schema":{"type":"string","description":"Stripe webhook signature"},"required":true,"description":"Stripe webhook signature","name":"stripe-signature","in":"header"}],"responses":{"200":{"description":"Event acknowledged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeWebhookAck"}}}},"400":{"description":"Signature mismatch / malformed request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Stripe is not configured on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"webhooks":{}}