Communications & Productivity

Mailbox, messaging, domain management, calendar, scheduling, and email-list management for Backbuild organizations.

197 endpoints. Generated from the OpenAPI 3.1 specification.

POST /v1/bbmail/attachments

Upload an attachment

Content-addresses an attachment to object storage under the caller's org/mailbox prefix. The caller must pass `mailboxId` as a query parameter and send the raw file bytes as the request body (`application/octet-stream`). Returns the SHA-256 content hash and byte length; pass the `sha256` in a subsequent send request. The per-file limit is 25 MiB. Returns `413 Payload Too Large` when the declared `Content-Length` or actual body exceeds 25 MiB.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7) that will own the attachment. Caller must have `can_write` on this mailbox.

Responses

StatusDescription
201 Attachment stored. Returns the SHA-256 hash and byte length for use in send requests.
400 `VALIDATION_ERROR` — empty body or `INVALID_ID_FORMAT` — invalid `mailboxId`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 `NOT_FOUND` — mailbox not found or caller lacks `can_write`.
413 `PAYLOAD_TOO_LARGE` — file exceeds 25 MiB.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
503 `SERVICE_UNAVAILABLE` — attachment storage not configured.
201 response body: data fields
FieldTypeDescription
sha256 string Hex SHA-256 of the stored file. Use this value in `MessageSendRequest.attachments[].sha256`.
size integer Stored byte length.
contentType string Detected or declared MIME type.
GET /v1/bbmail/attachments/{sha256}

Stream an attachment

Streams a previously-uploaded attachment by its SHA-256 content hash. The `mailboxId` query parameter is required. Non-executable content types are served inline with `nosniff`; all others are served as `application/octet-stream` with `Content-Disposition: attachment`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sha256 path string yes SHA-256 hex digest of the attachment (64 lowercase hex characters).
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 Attachment bytes.
400 `INVALID_ID_FORMAT` or `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/bbmail/domains

List sending domains

Returns all mail sending domains linked to the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 List of domains.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/domains

Link a sending domain

Links a domain to the caller's organization for use as a mail sending domain. Returns the domain record with the DNS records that must be published to verify ownership and configure routing.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
domain string yes The domain name to add (e.g. `mail.example.com`).

Responses

StatusDescription
201 Domain linked.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
409 `CONFLICT` — domain already linked or quota exceeded.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
domain string<hostname>
verified boolean
dns_verified boolean
ses_enabled boolean
created_at string<date-time>
GET /v1/bbmail/domains/{domainId}

Get a sending domain

Returns a single sending domain including its verification status and required DNS records.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 Domain record.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
domain string<hostname>
verified boolean
dns_verified boolean
ses_enabled boolean
created_at string<date-time>
POST /v1/bbmail/domains/{domainId}/provision

Auto-provision Cloudflare DNS and email routing

Drives Cloudflare DNS and Email-Routing provisioning for a Cloudflare-hosted domain. Attempts provider-based ownership proof via the organization's connected Cloudflare account before provisioning. Returns a structured per-step result in all cases; inspect the `code` field to determine the outcome (`OK`, `PARTIAL`, `OWNERSHIP_NOT_PROVEN`, `DOMAIN_NOT_ON_CLOUDFLARE`, `NEEDS_PROVIDER_CONNECTION`, `DOMAIN_ALREADY_CLAIMED`).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 Provisioning succeeded or partially succeeded. Inspect `data.code` for the per-step result.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 The domain is already claimed by another organization (`DOMAIN_ALREADY_CLAIMED`).
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `OWNERSHIP_NOT_PROVEN` or `NEEDS_PROVIDER_CONNECTION`.
422 Domain is not present in the organization's connected Cloudflare account (`DOMAIN_NOT_ON_CLOUDFLARE`).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/domains/{domainId}/ses-onboard

Onboard domain to AWS SES for sending

Drives SES identity creation, Easy-DKIM, and MAIL-FROM configuration for a verified domain. Requires a proven ownership timestamp on the domain. Returns a structured per-step result; `503` when SES is not configured server-side.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 SES onboarding succeeded or partially succeeded.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 `DOMAIN_NOT_FOUND` — domain does not exist in this organization.
409 `CONFLICT` — ownership not proven or an immutable state precondition was not met.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
503 `SERVICE_UNAVAILABLE` — SES onboarding is not configured.
POST /v1/bbmail/domains/{domainId}/ses-verify

Poll SES verification status

Polls SES for send-readiness (DKIM, MAIL-FROM) and performs an MX reachability probe for receive-readiness, persisting the results. Requires proven ownership. Returns `409` when ownership is not proven.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 SES verification polling completed.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — ownership not proven.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
503 `SERVICE_UNAVAILABLE` — SES is not configured.
POST /v1/bbmail/domains/{domainId}/verify

Verify domain ownership via DNS TXT

Triggers an ownership verification check by performing a DNS-over-HTTPS lookup for the `_bbmail-verify.<domain>` TXT record and passing the observed value to the server. The server (not the route) makes the ownership decision. Returns the updated domain record with the new verification status.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 Verification check completed. The body contains the updated domain record; inspect `ownership_verified_at` to determine if ownership was confirmed.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
domain string<hostname>
verified boolean
dns_verified boolean
ses_enabled boolean
created_at string<date-time>
POST /v1/bbmail/domains/{domainId}/verify-dns

Re-check published DNS records

Re-checks the live DNS records (MX, SPF, DKIM CNAME, DMARC) for a domain whose ownership has already been verified, and advances the per-record-class verification flags so the setup wizard can display per-step status. Requires `ownership_verified_at` to be set on the domain; returns `409 CONFLICT` otherwise.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
domainId path string<uuid> yes Domain identifier (UUIDv7).

Responses

StatusDescription
200 DNS check completed. The body contains the updated verification flags.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 `CONFLICT` — domain ownership must be verified before DNS verification.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/bbmail/filters

List message filters

Returns all message filters defined for the specified mailbox, ordered by `ordinal`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 List of filters.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/filters

Create a message filter

Creates a new message filter rule in the specified mailbox. `criteria` and `actions` are structured JSON objects validated server-side.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Mailbox to add the filter to.
criteria object yes Filter matching criteria (from, to, subject, body, has_attachment). Schema enforced server-side.
actions object yes Filter actions to apply on match (label, archive, delete, mark_read, forward, star). Schema enforced server-side.
ordinal integer no Sort order for filter evaluation (default 0).
enabled boolean no Whether the filter is active (default true).

Responses

StatusDescription
201 Filter created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
mailbox_id string<uuid>
name string
criteria object Filter criteria (from/to/subject/body/has_attachment).
actions array of object
enabled boolean
created_at string<date-time>
PATCH /v1/bbmail/filters/{filterId}

Update a message filter

Updates one or more filter properties. `mailboxId` is required in the body.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
filterId path string<uuid> yes Filter identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Mailbox that owns the filter.
criteria object no
actions object no
ordinal integer no
enabled boolean no

Responses

StatusDescription
200 Updated filter.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
mailbox_id string<uuid>
name string
criteria object Filter criteria (from/to/subject/body/has_attachment).
actions array of object
enabled boolean
created_at string<date-time>
DELETE /v1/bbmail/filters/{filterId}

Delete a message filter

Deletes a message filter. The `mailboxId` query parameter is required.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
filterId path string<uuid> yes Filter identifier (UUIDv7).
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 Filter deleted.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/filters/{filterId}/run

Run a message filter

Authorizes and returns the validated filter specification so the mailbox Durable Object can apply it over its hot message index. The route does not mutate message state directly — mutation is handled via the WebSocket protocol in the Durable Object.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
filterId path string<uuid> yes Filter identifier (UUIDv7).
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 Filter spec authorized. The payload contains the filter spec for the Durable Object to execute.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/inbound-smtp

Receive inbound message via SMTP hook (public webhook)

Public MTA-hook endpoint called by the self-hosted Stalwart inbound SMTP fleet at the DATA stage. Accepts a JSON envelope containing the raw RFC 822 message, SMTP envelope, and edge-computed SPF/DKIM/DMARC verdicts signed with an HMAC. After signature verification the handler resolves the recipient address to a mailbox, durably writes the raw message to object storage (the commit point), then asynchronously writes the catalog row and projects the message index. Returns `{ action: "discard" }` on success to instruct the MTA to drop the message from its spool. A `503` response signals a temporary failure; the MTA or its local spool should retry.

Auth Provider webhook signature

Request Body

FieldTypeRequiredDescription
context object no MTA connection context.
envelope object no SMTP envelope.
message object no Raw message reference.
spf_pass boolean no SPF check outcome.
dkim_pass boolean no DKIM check outcome.
dmarc_pass boolean no DMARC check outcome.

Responses

StatusDescription
200 Message accepted. `action: discard` instructs the MTA to remove the message from its spool.
400 Malformed request body.
403 HMAC signature verification failed.
411 Content-Length header is absent or invalid.
413 Request body exceeds the 25 MiB per-message limit.
429 Rate limit exceeded.
503 Service not configured or temporary upstream failure. The MTA should retry.
GET /v1/bbmail/labels

List labels

Returns all labels in the specified mailbox including their hierarchy.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 List of labels.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/labels

Create a label

Creates a new label in the specified mailbox. Labels can be nested by supplying a `parentId`.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Mailbox to create the label in.
name string yes Label display name.
parentId string<uuid> no Parent label for nesting.
color string no Optional color token.
ordinal integer no Sort order within the label list.

Responses

StatusDescription
201 Label created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
mailbox_id string<uuid>
name string
color string
created_at string<date-time>
PATCH /v1/bbmail/labels/{labelId}

Update a label

Updates one or more label properties. `mailboxId` is required in the body. All other fields are optional.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
labelId path string<uuid> yes Label identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Mailbox that owns the label.
name string no
color string no
ordinal integer no
parentId string<uuid> no

Responses

StatusDescription
200 Updated label.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
mailbox_id string<uuid>
name string
color string
created_at string<date-time>
DELETE /v1/bbmail/labels/{labelId}

Delete a label

Deletes a label from a mailbox. The `mailboxId` query parameter is required.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
labelId path string<uuid> yes Label identifier (UUIDv7).
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 Label deleted.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/bbmail/mailboxes

List mailboxes

Returns the mailboxes the caller owns or has been delegated access to within the authenticated organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 List of mailboxes.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/bbmail/mailboxes

Create a mailbox

Creates a new mailbox under a verified sending domain in the caller's organization. The organization is taken from the authenticated session and is never accepted in the request body.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
domainId string<uuid> yes Domain identifier.
localPart string yes Local part (before `@`).
displayName string no Optional display name.
planTier string (enum) freepaid no Service tier for the mailbox (`free` or `paid`).

Responses

StatusDescription
201 Mailbox created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 `NOT_FOUND` — the referenced domain does not exist or is not visible to this organization.
409 `CONFLICT` — a mailbox with that local-part already exists on this domain.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid> Mailbox identifier (UUIDv7).
org_id string<uuid> Owning organization identifier.
domain_id string<uuid> Associated domain identifier.
local_part string Local part of the email address (the part before `@`).
display_name string Optional display name.
plan_tier string (enum) freepaid Service tier for the mailbox (`free` or `paid`).
created_at string<date-time>
updated_at string<date-time>
GET /v1/bbmail/messages

List messages

Returns a paginated list of messages in the specified mailbox, optionally filtered by direction.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).
direction query string (enum) no Filter by message direction.
limit query integer no Maximum messages to return (1–100).
offset query integer no Number of messages to skip.

Responses

StatusDescription
200 Paginated message list.
400 `INVALID_ID_FORMAT` or `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/bbmail/messages/{messageId}

Get a message

Returns a single message by id. The `mailboxId` query parameter is required. A message the caller cannot access is reported as `404 NOT_FOUND`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
messageId path string<uuid> yes Message identifier (UUIDv7).
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 The message record.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
mailbox_id string<uuid>
org_id string<uuid>
direction string (enum) inoutdraft
subject string
from_addr string
snippet string
thread_key string
size_bytes integer
has_attachments boolean
spam_verdict string
r2_raw_key string Never echoed to the client. Present only in the internal ingest body; omitted from responses.
body_raw string Raw RFC 2822 message body (present only in the `GET /messages/{messageId}` response when the object is available in storage).
created_at string<date-time>
POST /v1/bbmail/messages/{messageId}/labels

Apply or remove a message label (WebSocket-only operation)

Message label mutations are performed over the mailbox WebSocket (`GET /v1/bbmail/ws`), not via REST. Connect to the mailbox socket and send the `MSG_LABEL` operation; the change is applied in the mailbox Durable Object and durably audited via the signed audit flush. This REST endpoint exists to return a machine-readable error rather than silently returning `404`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
messageId path string<uuid> yes Message identifier (UUIDv7).

Responses

StatusDescription
400 `INVALID_ID_FORMAT` — invalid `messageId`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
409 `VALIDATION_ERROR` with `ws_only: true` — this operation must be performed over the mailbox WebSocket.
POST /v1/bbmail/messages/{messageId}/move

Move a message (WebSocket-only operation)

Message-folder moves are performed over the mailbox WebSocket (`GET /v1/bbmail/ws`), not via REST. Connect to the mailbox socket and send the `MSG_MOVE` operation; the change is applied in the mailbox Durable Object and durably audited via the signed audit flush. This REST endpoint exists to return a machine-readable error rather than silently returning `404`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
messageId path string<uuid> yes Message identifier (UUIDv7).

Responses

StatusDescription
400 `INVALID_ID_FORMAT` — invalid `messageId`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
409 `VALIDATION_ERROR` with `ws_only: true` — this operation must be performed over the mailbox WebSocket.
POST /v1/bbmail/messages/send

Send a message

Sends an outbound email from the specified mailbox. The `From` identity is resolved server-side from the mailbox record; callers cannot override it. All attachments must be pre-uploaded via `POST /v1/bbmail/attachments`; only content-addressed references (`sha256`) are accepted here. The combined `to + cc + bcc` count must not exceed the platform MAX_RECIPIENTS limit. In restricted (non-production) environments outbound recipients are checked against the org's verified domains and current org members. An optional `Idempotency-Key` header (max 256 chars) enables safe retries.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Sending mailbox identifier.
to array of string yes Primary recipients (max 50).
cc array of string no CC recipients (max 50).
bcc array of string no BCC recipients (max 50).
subject string yes Message subject (RFC 5322 limit: 998 chars).
html string no HTML body (max 2 MiB).
text string no Plain-text body (max 2 MiB).
replyTo string<email> no Optional `Reply-To` address.
inReplyTo string no Message-ID of the message being replied to.
attachments array of object no Attached files (max 32). Each file must be pre-uploaded via POST /v1/bbmail/attachments.

Responses

StatusDescription
200 Message accepted by the sending provider.
400 `VALIDATION_ERROR` — invalid recipients, `TOO_MANY_RECIPIENTS`, subject too long, too many attachments, or `ATTACHMENT_NOT_FOUND`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
402 `QUOTA_EXCEEDED` — send quota exceeded; top up credits.
403 `FORBIDDEN` — cannot send from this mailbox or `RESTRICTED_ENV` recipient refusal.
404 `NOT_FOUND` — mailbox not found or access denied.
409 `CONFLICT` — all recipients suppressed or daily send cap reached.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
502 `DATABASE_ERROR` — provider dispatch error.
503 `SERVICE_UNAVAILABLE` — email sending not configured, suppression check unavailable, or runtime unavailable.
200 response body: data fields
FieldTypeDescription
sent boolean (enum) true
provider string Provider that accepted the message (e.g. `ses`).
messageId string Provider-assigned message identifier.
suppressed array of string Recipients that were silently suppressed (on the global suppression list).
GET /v1/bbmail/settings

Get mailbox settings

Returns the caller's per-user preferences for the specified mailbox.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7).

Responses

StatusDescription
200 Current mailbox settings.
400 `INVALID_ID_FORMAT` — `mailboxId` is not a valid UUID.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
mailbox_id string<uuid>
reading_pane string (enum) belowrightoff
density string (enum) comfortablecozycompact
conversation_view boolean
custom_signature_html string
undo_send_seconds integer (enum) 05102030
mark_read_mode string (enum) immediateafter_secondsmanual
mark_read_delay_ms integer
updated_at string<date-time>
PATCH /v1/bbmail/settings

Update mailbox settings

Upserts the caller's per-user preferences for the specified mailbox. All fields are optional; only supplied fields are updated.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
mailboxId string<uuid> yes Mailbox whose settings to update.
reading_pane string (enum) belowrightoff no Reading pane layout.
density string (enum) comfortablecozycompact no Message list density.
conversation_view boolean no Group messages by conversation thread.
custom_signature_html string no HTML signature appended to outbound messages. Pass `null` to clear.
undo_send_seconds integer (enum) 05102030 no Undo-send delay in seconds.
mark_read_mode string (enum) immediateafter_secondsmanual no When messages are automatically marked read.
mark_read_delay_ms integer no Delay before marking read (applies when `mark_read_mode` is `after_seconds`).

Responses

StatusDescription
200 Updated mailbox settings.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
mailbox_id string<uuid>
reading_pane string (enum) belowrightoff
density string (enum) comfortablecozycompact
conversation_view boolean
custom_signature_html string
undo_send_seconds integer (enum) 05102030
mark_read_mode string (enum) immediateafter_secondsmanual
mark_read_delay_ms integer
updated_at string<date-time>
GET /v1/bbmail/ws

Open mailbox WebSocket

Upgrades an HTTP connection to a WebSocket channel connected to the caller's mailbox Durable Object. The caller must supply a one-time `token` query parameter (a short-lived JWT minted by the session) and the `mailboxId` to connect to. The server verifies the token, checks revocation, and runs the mailbox effective-access gate before forwarding the upgrade. A connection without `Upgrade: websocket` receives `426 Upgrade Required`. The capability (`read` or `write`) is derived from the access verdict and forwarded to the Durable Object, which re-verifies independently. Authentication is via the `token` query parameter (`oneTimeTicket` scheme) — a standard `Authorization` header is not supported on WebSocket upgrades.

Auth One-time ?token= ticket

Parameters

NameInTypeRequiredDescription
token query string yes One-time mailbox connection ticket (short-lived JWT). Minted by an authenticated REST call; redeemable once.
mailboxId query string<uuid> yes Mailbox identifier (UUIDv7) to connect to.

Responses

StatusDescription
101 WebSocket handshake accepted. The connection is proxied to the mailbox Durable Object. Messages follow the BB Mail WS protocol.
400 `VALIDATION_ERROR` — `token` or `mailboxId` query parameter is missing or invalid.
401 `AUTH_TOKEN_INVALID` or `AUTH_TOKEN_EXPIRED` — the one-time token is malformed, expired, or has been revoked.
403 `PERMISSION_DENIED` — the caller has no read access to this mailbox (uniform deny; does not distinguish absent from forbidden).
426 `VALIDATION_ERROR` — the request did not include `Upgrade: websocket`.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/access-requests

Request calendar access

Submits an access request for a calendar by id or owner email. An optional email notification can be sent to the calendar owner.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
calendar_id string<uuid> no Target calendar id.
owner_email string no Owner email to look up the calendar by.
capability string (enum) freebusydetailswrite no Requested access level.
message string no Optional message to the calendar owner.
send_email boolean no Send an email notification to the calendar owner.

Responses

StatusDescription
201 Access request submitted.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/appointment-schedules

List appointment schedules

Returns the caller's appointment booking schedules. Optionally filter by `calendar_id`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendar_id query string<uuid> no Filter by calendar (UUIDv7).

Responses

StatusDescription
200 Appointment schedules.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PUT /v1/calendar/appointment-schedules

Create or update an appointment schedule

Upserts an appointment booking schedule. Supply `id` to update an existing schedule; omit to create a new one. Returns `201` on create, `200` on update.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
id string<uuid> no Omit to create; supply to update in-place.
calendar_id string<uuid> yes Calendar that owns the schedule.
title string yes
slug string no URL-safe booking page slug (auto-generated from title when omitted).
slot_minutes integer no Duration of each bookable slot in minutes.
buffer_minutes integer no Buffer time between appointments.
max_per_day integer no Maximum bookings per day (null = unlimited).
availability array of object no Weekly availability windows. Each item specifies a weekday/start/end window.
booking_form object no Custom fields to collect from bookers. Validated by the stored procedure.
window_start string no Earliest bookable date (ISO-8601).
window_end string no Latest bookable date (ISO-8601).
conflict_calendar_ids array of string no Calendars to check for conflicts when determining availability.

Responses

StatusDescription
200 Appointment schedule updated.
201 Appointment schedule created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/appointment-schedules/{scheduleId}

Get an appointment schedule

Returns a single appointment booking schedule.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
scheduleId path string<uuid> yes Appointment schedule identifier (UUIDv7).

Responses

StatusDescription
200 Appointment schedule.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/book/{slug}

Get public booking page (public)

Returns the public-safe appointment schedule metadata for a booking page slug, including optionally the freebusy-level busy intervals for a `[from, to]` window (clamped server-side to 62 days). An unknown slug returns `404`. Rate-limited per IP.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
slug path string yes Appointment schedule slug.
from query string<date-time> no Busy-window start (ISO-8601). Required if `to` is provided.
to query string<date-time> no Busy-window end (ISO-8601). Required if `from` is provided.

Responses

StatusDescription
200 Booking page data.
404 `NOT_FOUND` — slug not found.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
POST /v1/calendar/book/{slug}

Create a booking (public)

Creates an appointment booking via the public booking page. Requires a valid Cloudflare Turnstile token in `cf-turnstile-response` (evaluated server-side; the field is stripped before storage). The server resolves the schedule by slug, conflict-checks the slot, and creates the event and confirmation email.

Public Public: no authentication

Request Body

FieldTypeRequiredDescription
booker_email string<email> yes
starts_at string yes Requested slot start (ISO-8601 or RFC 3339).
booker_name string no
answers object no Answers to custom booking-form fields defined on the schedule.
cf-turnstile-response string no Cloudflare Turnstile challenge response token. Consumed server-side to prevent abuse; stripped before storage.

Responses

StatusDescription
201 Booking created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
404 `NOT_FOUND` — slug not found or schedule is disabled.
409 `CONFLICT` — the requested time slot is no longer available.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/book/manage/{booking_token}

Get booking details for management (public)

Resolves a per-booking management token and returns the booker-safe booking details. Internal fields (`org_id`, owner user id, created event id) are never returned. Rate-limited per IP.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
booking_token path string yes Per-booking management token (16–256 URL-safe characters).

Responses

StatusDescription
200 Booking details.
404 `NOT_FOUND` — token not found or expired.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
200 response body: data fields
FieldTypeDescription
id string<uuid>
schedule_title string
starts_at string<date-time>
ends_at string<date-time>
attendee_name string
attendee_email string<email>
status string (enum) confirmedcancelledrescheduled
notes string
POST /v1/calendar/book/manage/{booking_token}

Cancel or reschedule a booking (public)

Cancels or reschedules a booking via the per-booking management token. Requires a valid Cloudflare Turnstile token in `cf-turnstile-response`. `reschedule` requires `starts_at`.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
booking_token path string yes Per-booking management token (16–256 URL-safe characters).

Request Body

FieldTypeRequiredDescription
action string (enum) cancelreschedule yes
starts_at string no New slot start (ISO-8601). Required when `action` is `reschedule`.
reason string no Optional cancellation or reschedule reason.
cf-turnstile-response string no Cloudflare Turnstile challenge response token.

Responses

StatusDescription
200 Booking updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
404 `NOT_FOUND` — token not found.
409 `CONFLICT` — requested reschedule slot is unavailable.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/calendars

List calendars

Returns the calendars visible to the caller in their organization. Pass `include_hidden=true` to include hidden calendars.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
include_hidden query boolean no Include hidden calendars when `true`.

Responses

StatusDescription
200 List of calendars.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/calendars

Create a calendar

Creates a new calendar in the caller's organization. All fields are optional; defaults are assigned by the platform.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string no
kind string (enum) primarysecondaryresourcesubscribed_urlinterestbirthday no
timezone string no
default_color integer no Color slot (0–11).
description string no
public_visibility string (enum) nonefreebusydetails no

Responses

StatusDescription
201 Calendar created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
201 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
owner_user_id string<uuid>
name string
color string
timezone string
hidden boolean
default boolean
created_at string<date-time>
updated_at string<date-time>
GET /v1/calendar/calendars/{calendarId}

Get a calendar

Returns a single calendar. A calendar the caller cannot see is reported as `404 NOT_FOUND`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Responses

StatusDescription
200 Calendar record.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
owner_user_id string<uuid>
name string
color string
timezone string
hidden boolean
default boolean
created_at string<date-time>
updated_at string<date-time>
PATCH /v1/calendar/calendars/{calendarId}

Update a calendar

Updates calendar properties. All fields are optional; `name: null` clears the name.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
name string no
description string no
timezone string no
default_color integer no
public_visibility string (enum) nonefreebusydetails no
status string (enum) activehiddenarchived no

Responses

StatusDescription
200 Updated calendar.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
200 response body: data fields
FieldTypeDescription
id string<uuid>
org_id string<uuid>
owner_user_id string<uuid>
name string
color string
timezone string
hidden boolean
default boolean
created_at string<date-time>
updated_at string<date-time>
DELETE /v1/calendar/calendars/{calendarId}

Delete a calendar

Deletes a calendar.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Responses

StatusDescription
200 Calendar deleted.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/calendars/{calendarId}/acl

List calendar ACL entries

Returns the access-control list for a calendar. Pass `include_revoked=true` to include revoked grants.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).
include_revoked query boolean no Include revoked grants when `true`.

Responses

StatusDescription
200 ACL entries.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PUT /v1/calendar/calendars/{calendarId}/acl

Grant or revoke a calendar share

Adds, updates, or revokes a share grant for a calendar. Requires `can_admin` on the calendar.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
action string (enum) grantrevoke no
share_id string<uuid> no Share record to update (optional; omit to create).
scope string (enum) usergroupdepartmentprojectorgpublic no
target_id string no Target identifier (user id, group id, etc.). Null for org/public scope.
is_public boolean no
recipient_org_id string<uuid> no
recipient_user_id string<uuid> no
capability string (enum) freebusydetailswriteadmin no Access level to grant.

Responses

StatusDescription
200 Share grant applied.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/calendars/{calendarId}/settings

Get per-calendar settings

Returns the caller's per-calendar settings.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Responses

StatusDescription
200 Per-calendar settings.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PATCH /v1/calendar/calendars/{calendarId}/settings

Update per-calendar settings

Updates the caller's per-calendar settings. Body is a free-form JSON object; `org_id` and `calendar_id` are pinned from the session and path.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
calendarId path string<uuid> yes Calendar identifier (UUIDv7).

Request Body

Key-value settings bag; validated server-side.

Responses

StatusDescription
200 Updated settings.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/events

List events in a time window

Returns events across the caller's visible calendars within the `[from, to]` ISO-8601 window. Recurring event masters are expanded server-side into concrete occurrences within the window. `calendars` is an optional comma-separated list of calendar UUIDs to restrict the query.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
from query string<date-time> yes Window start (ISO-8601 timestamp).
to query string<date-time> yes Window end (ISO-8601 timestamp).
calendars query string no Comma-separated calendar UUIDs to restrict the query.

Responses

StatusDescription
200 Events in the window.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/events

Create an event

Creates a new event (or recurring series master / override) in the specified calendar. Timing, attendees, RRULE, reminders, and conferencing are validated server-side.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
calendar_id string<uuid> yes
recurrence_role string (enum) singlemasteroverride no
series_master_id string<uuid> no
recurrence_id string no
title string no
description_html string no
location string no
starts_at string no ISO-8601 timestamp or RFC 3339 date-time string.
ends_at string no
start_date string no All-day start date (YYYY-MM-DD).
end_date string no
start_tz string no
end_tz string no
is_all_day boolean no
event_type string no
color_id integer no
visibility string (enum) defaultpublicprivateconfidential no
transparency string (enum) opaquetransparent no
status string (enum) confirmedtentativecancelled no
rrule string no RFC 5545 RRULE.
rdate string no
exdate string no
guests_can_invite boolean no
guests_can_modify boolean no
guests_can_see_others boolean no
conferencing object no
attachments array of object no
reminders_use_default boolean no
reminders array of object no
attendees array of object no
event_type_props object no
extended_props object no

Responses

StatusDescription
201 Event created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/events/{eventId}

Get an event

Returns a single event. The `calendar_id` query parameter is required.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).
calendar_id query string<uuid> yes Calendar identifier (UUIDv7).

Responses

StatusDescription
200 Event record.
400 `INVALID_ID_FORMAT` — `eventId` or `calendar_id` is invalid.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PATCH /v1/calendar/events/{eventId}

Update an event

Updates event fields. `calendar_id` query parameter is required. For recurring events, `scope` controls whether the edit applies to `this` occurrence, `this_and_following`, or `all`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).
calendar_id query string<uuid> yes Calendar identifier (UUIDv7).
scope query string (enum) no Recurrence edit scope (`this`, `this_and_following`, `all`).

Request Body

FieldTypeRequiredDescription
calendar_id string<uuid> no
title string no
description_html string no
location string no
starts_at string no
ends_at string no
start_date string no
end_date string no
start_tz string no
end_tz string no
is_all_day boolean no
visibility string (enum) defaultpublicprivateconfidential no
transparency string (enum) opaquetransparent no
status string (enum) confirmedtentativecancelled no
rrule string no
rdate string no
exdate string no
conferencing object no
reminders_use_default boolean no
reminders array of object no
attendees array of object no

Responses

StatusDescription
200 Updated event.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
DELETE /v1/calendar/events/{eventId}

Delete an event

Deletes an event. `calendar_id` query parameter is required. For recurring events, `scope` and `recurrence_id` control which occurrences are removed.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).
calendar_id query string<uuid> yes Calendar identifier (UUIDv7).
scope query string (enum) no Recurrence delete scope.
recurrence_id query string no Specific recurrence occurrence id.

Responses

StatusDescription
200 Event deleted.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/events/{eventId}/move

Move event to another calendar

Moves an event from one calendar to another within the same organization.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
source_calendar_id string<uuid> yes Calendar to move the event from.
dest_calendar_id string<uuid> yes Calendar to move the event to.

Responses

StatusDescription
200 Event moved.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/events/{eventId}/publish

Publish or unpublish an event

Publishes an event to a public render token, or unpublishes it. `calendar_id` query parameter is required.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).
calendar_id query string<uuid> yes Calendar identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
calendar_id string<uuid> no Owning calendar. Overridden by the query parameter.
action string (enum) publishunpublish no `publish` issues a public render token; `unpublish` revokes it.
show_fields array of string no Allowlist of event fields to expose in the public render.

Responses

StatusDescription
200 Event publish state updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PUT /v1/calendar/events/{eventId}/reminders

Set event reminders

Replaces the caller's reminder settings for an event.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
calendar_id string<uuid> no Owning calendar (optional; resolved from event when omitted).
reminders_use_default boolean no When `true`, apply the calendar's default reminder rules instead of the explicit `reminders` list.
reminders array of object no Explicit reminder definitions. Each item is a JsonObject validated by the stored procedure.

Responses

StatusDescription
200 Reminders updated.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/events/{eventId}/rsvp

RSVP to an event

Records the caller's RSVP response for an event invitation. Supports proposing an alternative time.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
eventId path string<uuid> yes Event identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
response_status string (enum) accepteddeclinedtentativeneedsAction no RSVP response.
comment string no Optional message to the organizer.
proposed_start string no Counter-proposed start (ISO-8601 timestamp).
proposed_end string no Counter-proposed end (ISO-8601 timestamp).
proposed_message string no
additional_guests array of object no

Responses

StatusDescription
200 RSVP recorded.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/feeds/{token}/basic.ics

Download ICS calendar feed (public)

Resolves a secret or public ICS feed token and returns a well-formed `text/calendar` iCalendar document. The token is validated constant-time; an invalid, revoked, or visibility-`none` token returns `404 NOT_FOUND` with no distinguishing information. Rate-limited per IP at 120 requests per minute.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
token path string yes High-entropy feed token (16–256 URL-safe characters).

Responses

StatusDescription
200 iCalendar feed.
404 `NOT_FOUND` — feed token not found or visibility is `none`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
GET /v1/calendar/freebusy

Query free/busy

Returns busy intervals for one or more calendars or users within the `[from, to]` window. `calendars` and `users` are optional comma-separated UUID lists.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
from query string<date-time> yes Window start (ISO-8601).
to query string<date-time> yes Window end (ISO-8601).
calendars query string no Comma-separated calendar UUIDs.
users query string no Comma-separated user UUIDs.

Responses

StatusDescription
200 Free/busy intervals.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/public/{render_token}

Get a published event (public)

Resolves a high-entropy render token and returns the published, server-redacted event JSON. The token is validated constant-time; an invalid, revoked, or missing token returns `404`. The raw token is never echoed in the response.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
render_token path string yes High-entropy render token (16–256 URL-safe characters).

Responses

StatusDescription
200 Published event.
404 `NOT_FOUND` — token not found or revoked.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
200 response body: data fields
FieldTypeDescription
event object Server-redacted event fields.
GET /v1/calendar/search

Search events

Full-text search across the caller's visible events. `q` is required; `who`, `where`, `from`, `to`, and `limit` (1–200) are optional filters.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
q query string yes Search query string.
who query string no Filter by attendee name or email.
where query string no Filter by location.
from query string<date-time> no Search window start (ISO-8601).
to query string<date-time> no Search window end (ISO-8601).
limit query integer no Max results (1–200).

Responses

StatusDescription
200 Search results.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/settings

Get account-wide calendar settings

Returns the caller's account-wide calendar preferences.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Account calendar settings.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PATCH /v1/calendar/settings

Update account-wide calendar settings

Updates the caller's account-wide calendar preferences. Body is a free-form JSON object; `org_id` is pinned from the session.

Auth Session JWT (Bearer)

Request Body

Settings key-value bag.

Responses

StatusDescription
200 Updated settings.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/sync

List calendar sync connections

Returns the caller's external calendar provider connections. Optionally filter by `provider`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
provider query string (enum) no Filter by provider (`google`, `microsoft`, `caldav`).

Responses

StatusDescription
200 Sync connections.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/sync/connect

Connect a calendar sync provider

Stores encrypted provider credentials and creates a sync connection. For CalDAV, supply `caldav_password` (plaintext over HTTPS); it is encrypted server-side before storage and is never returned. For Google and Microsoft, use the OAuth flow (`/sync/oauth/{provider}/start`) to obtain tokens and call this endpoint with encrypted token fields, or complete the OAuth flow directly via the OAuth callback routes.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
provider string (enum) googlemicrosoftcaldav yes External calendar provider.
provider_account_email string yes Email address for the provider account.
secret_kind string yes Type of credential being stored (e.g. `oauth2_refresh`, `app_password`).
encrypted_refresh_token string no
encrypted_access_token string no
token_expires_at string no
scopes array of string no
caldav_base_url string no CalDAV principal URL. Required when `provider` is `caldav`.
caldav_password string no CalDAV / app-specific password. Sent in plaintext over HTTPS; encrypted server-side. Required when `provider` is `caldav` and `secret_kind` is `app_password`.
create_integration_state boolean no

Responses

StatusDescription
201 Sync connection created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 403 Forbidden — authenticated but lacking the required membership, role, permission, MFA step-up, or feature entitlement.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/sync/oauth/google/callback

Google Calendar OAuth callback (browser redirect)

Handles the Google OAuth authorization callback. Validates the CSRF `state` parameter and one-time nonce, exchanges the authorization code for tokens, encrypts them, and stores the connection. Redirects the browser to the calendar settings page with `connected=google` or `sync_error=<reason>` on failure. A `?error=access_denied` from the provider redirects immediately without a token exchange.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
code query string no Authorization code from Google.
state query string no CSRF state token from the `/start` response.
error query string no Provider error code (e.g. `access_denied`).

Responses

StatusDescription
302 Redirect to calendar settings page.
400 `VALIDATION_ERROR` — missing/invalid `code`/`state`, or scope mismatch.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/sync/oauth/google/callback

Google Calendar OAuth callback (SPA form post)

Same as the GET callback but for SPAs that capture the authorization code client-side and POST `{ code, state }` as a JSON body.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string no
state string no

Responses

StatusDescription
302 Redirect to calendar settings page.
400 `VALIDATION_ERROR` or `AUTH_OAUTH_FAILED`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/sync/oauth/google/start

Start Google Calendar OAuth flow

Generates the Google consent URL for the Calendar sync OAuth flow. Returns the authorization URL and a CSRF-bound state token. The client should redirect the user to the returned `url`. Requires the `calendar` feature flag.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Authorization URL generated.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
503 `SERVICE_UNAVAILABLE` — Google calendar sync is not configured.
200 response body: data fields
FieldTypeDescription
url string<uri> Provider authorization URL. Redirect the user here to start the consent flow.
state string CSRF state token. Pass this back in the callback `state` parameter.
GET /v1/calendar/sync/oauth/microsoft/callback

Microsoft Calendar OAuth callback (browser redirect)

Handles the Microsoft OAuth callback — same contract as the Google GET callback.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
code query string no
state query string no
error query string no

Responses

StatusDescription
302 Redirect to calendar settings page.
400 `VALIDATION_ERROR` or `AUTH_OAUTH_FAILED`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/sync/oauth/microsoft/callback

Microsoft Calendar OAuth callback (SPA form post)

Same as the GET callback but accepts `{ code, state }` as a JSON body from an SPA.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string no
state string no

Responses

StatusDescription
302 Redirect to calendar settings page.
400 `VALIDATION_ERROR` or `AUTH_OAUTH_FAILED`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/sync/oauth/microsoft/start

Start Microsoft Calendar OAuth flow

Generates the Microsoft identity platform consent URL for the Calendar sync OAuth flow. Returns the authorization URL and CSRF state token. Requires the `calendar` feature flag.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Authorization URL generated.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
503 `SERVICE_UNAVAILABLE` — Microsoft calendar sync is not configured.
200 response body: data fields
FieldTypeDescription
url string<uri> Provider authorization URL. Redirect the user here to start the consent flow.
state string CSRF state token. Pass this back in the callback `state` parameter.
GET /v1/calendar/sync/providers/{connectionId}/calendars

List provider calendars for a connection

Fetches the list of calendars from the connected external provider (Google or Microsoft) for use in the sync picker. Refreshes the access token server-side if needed; the token is never returned to the caller. CalDAV connections are not supported by this endpoint.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
connectionId path string<uuid> yes Sync connection identifier (UUIDv7).

Responses

StatusDescription
200 Provider calendar list.
400 `INVALID_ID_FORMAT` or `VALIDATION_ERROR` (CalDAV connection).
401 `AUTH_OAUTH_FAILED` — the connection must be re-linked.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
502 `EXTERNAL_SERVICE_ERROR` — provider API request failed.
503 `SERVICE_UNAVAILABLE` — encryption not configured.
GET /v1/calendar/task-lists

List task lists

Returns the caller's task lists.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Task lists.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PUT /v1/calendar/task-lists

Create, rename, or delete a task list

Upserts a task list. `action` must be `create`, `rename`, or `delete`. `list_id` is required for `rename` and `delete`; `title` is required for `create` and `rename`.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
action string (enum) createrenamedelete yes
list_id string<uuid> no Required for `rename` and `delete`.
title string no Required for `create` and `rename`.

Responses

StatusDescription
200 Task list operation applied.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/tasks

Create a task

Creates a new task in the specified task list.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
list_id string<uuid> yes Task list to add the task to.
title string yes
notes string no
due_at string no Due date/time (ISO-8601 or RFC 3339).
ordinal integer no Ordinal position within the list.

Responses

StatusDescription
201 Task created.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
PATCH /v1/calendar/tasks/{taskId}

Update a task

Updates task fields. All fields are optional.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
taskId path string<uuid> yes Task identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
title string no
notes string no
due_at string no
status string (enum) needsActioncompleted no

Responses

StatusDescription
200 Updated task.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
DELETE /v1/calendar/tasks/{taskId}

Delete a task

Deletes a task. Pass `cascade=true` to also delete sub-tasks.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
taskId path string<uuid> yes Task identifier (UUIDv7).
cascade query boolean no Delete sub-tasks recursively.

Responses

StatusDescription
200 Task deleted.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/tasks/{taskId}/complete

Complete or reopen a task

Marks a task completed or reopens it. Pass `{ "completed": false }` to reopen.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
taskId path string<uuid> yes Task identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
completed boolean no Set `false` to reopen the task. Defaults to `true`.

Responses

StatusDescription
200 Task completion state updated.
400 `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
POST /v1/calendar/tasks/{taskId}/move

Move a task

Moves a task to a different list and/or changes its ordinal position.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
taskId path string<uuid> yes Task identifier (UUIDv7).

Request Body

FieldTypeRequiredDescription
list_id string<uuid> no Destination task list (optional; omit to reorder within the current list).
ordinal integer no Ordinal position in the destination list.

Responses

StatusDescription
200 Task moved.
400 400 Bad Request — a request parameter, body field, or the JSON body itself failed validation.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/calendar/ws

Open calendar WebSocket

Upgrades to a WebSocket channel connected to the calendar Durable Object. The caller supplies a one-time `token` (JWT) and the `calendarId`. The server verifies the token, checks revocation, and runs the four-bit calendar access gate (`can_read_freebusy` / `can_read_details` / `can_write` / `can_admin`) before forwarding the upgrade. The derived capability (`freebusy`, `read`, or `write`) is passed to the Durable Object, which re-verifies independently. A request without `Upgrade: websocket` receives `426`.

Auth One-time ?token= ticket

Parameters

NameInTypeRequiredDescription
token query string yes One-time calendar connection ticket (short-lived JWT).
calendarId query string<uuid> yes Calendar identifier (UUIDv7).

Responses

StatusDescription
101 WebSocket handshake accepted.
400 `VALIDATION_ERROR`.
401 `AUTH_TOKEN_INVALID` or `AUTH_TOKEN_EXPIRED`.
403 `PERMISSION_DENIED` — no calendar access (uniform deny).
426 `VALIDATION_ERROR` — not a WebSocket upgrade.
500 500 Internal Server Error — an unexpected server-side error. The message is sanitized; the correlation id is logged server-side.
GET /v1/email/unsubscribe

Unsubscribe confirmation page (public)

Browser-clickable GET endpoint for the RFC 2369 `List-Unsubscribe` header. Verifies the HMAC-signed `token` query parameter and renders a confirmation HTML page with a submit button. Does NOT mutate state — the form POSTs the verified token back to this endpoint to trigger the actual unsubscription. Link prefetchers and crawlers that follow the link will see only the confirmation page and cannot unsubscribe the recipient.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
token query string yes HMAC-SHA256-signed unsubscribe token (≤ 4096 chars).

Responses

StatusDescription
200 Confirmation page HTML.
400 Missing, oversized, or cryptographically invalid token.
429 Rate limit exceeded.
503 Unsubscribe endpoint not configured.
POST /v1/email/unsubscribe

One-click unsubscribe (public)

RFC 8058 one-click `List-Unsubscribe-Post` endpoint and confirmation form submission handler. Verifies the HMAC-signed token (via `?token=` query param, `application/x-www-form-urlencoded` body field, or JSON `token` field), then sets the marketing objection flag on the email address and adds it to the suppression list. Returns `{ unsubscribed: true, email: "..." }` on success. Per-IP rate-limited before any HMAC or database work.

Public Public: no authentication

Parameters

NameInTypeRequiredDescription
token query string no HMAC-SHA256-signed unsubscribe token (≤ 4096 chars). Can alternatively be supplied in the request body.

Request Body

FieldTypeRequiredDescription
token string no

Responses

StatusDescription
200 Unsubscription recorded.
400 Missing, oversized, or cryptographically invalid token.
429 Rate limit exceeded.
500 Internal error.
503 Endpoint not configured.
POST /v1/helpdesk/auto-dispatch

Set auto-dispatch for a category

Enables or disables automatic dispatch for a helpdesk category. ELEVATED: requires MFA step-up (human path); SP enforces elevated grant floor for API-key path.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
category_key string yes
auto_dispatch boolean yes
saas_package_id string no Optional SaaS package scope (hex UUID).
project_id string<uuid> no
dispatch_policy object no

Responses

StatusDescription
200 Auto-dispatch setting saved.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
POST /v1/helpdesk/categories

Create or update a helpdesk dispatch category

Creates or updates a helpdesk category configuration entry, including inheritance columns, auto-dispatch settings, and dispatch-policy overrides. SP self-gates on `support.config` / `org.update`.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
key string yes Category key.
label string yes Category display label.
saas_package_id string no SaaS package scope (hex UUID).
project_id string<uuid> no Project scope.
sort_order integer no Sort order.
is_active boolean no
overrides_key string no Parent category key this entry overrides.
is_shadow_disabled boolean no
auto_dispatch boolean no
dispatch_policy object no Dispatch policy configuration.

Responses

StatusDescription
200 Category saved.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
DELETE /v1/helpdesk/categories/{categoryId}

Delete a helpdesk category

Deletes a helpdesk category row by ID. SP self-gates on `support.config`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
categoryId path string<uuid> yes Category ID.

Responses

StatusDescription
200 Category deleted.
400 Invalid ID format. `error.code`: `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/helpdesk/categories/effective

List effective helpdesk categories

Returns the merged effective category set for a given `saas_package_id` and/or `project_id` tuple. This is the single source of truth for the ticket editor. SP self-gates on `support.read`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
saas_package_id query string no SaaS package ID (hex UUID) to scope effective categories.
project_id query string<uuid> no Project ID to scope effective categories.

Responses

StatusDescription
200 Effective category list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/helpdesk/category-workers

List VW-to-category assignments

Returns virtual worker assignments for helpdesk categories. Supports optional `category_key`, `saas_package_id`, and `project_id` filters.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
category_key query string no
saas_package_id query string no
project_id query string<uuid> no

Responses

StatusDescription
200 Worker assignment list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/helpdesk/category-workers

Assign a virtual worker to a helpdesk category

Associates a virtual worker with a helpdesk dispatch category. Optionally scoped to a SaaS package or project. The virtual worker must be accessible to the caller (cross-org reject enforced at SP).

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
category_key string yes Category to assign the worker to.
virtual_worker_id string<uuid> yes Virtual worker ID.
saas_package_id string no Optional SaaS package scope (hex UUID).
project_id string<uuid> no Optional project scope.
priority integer no Assignment priority (lower = higher priority).
is_enabled boolean no

Responses

StatusDescription
201 Worker assigned.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
DELETE /v1/helpdesk/category-workers/{assignmentId}

Remove a VW-to-category assignment

Removes a virtual worker assignment by assignment ID. SP self-gates on `support.config`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
assignmentId path string<uuid> yes Assignment ID.

Responses

StatusDescription
200 Assignment removed.
400 Invalid ID format. `error.code`: `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/helpdesk/pool-policy

Set container pool policy

Configures the container pool limits and timing policy for the organization's helpdesk workers. Requires MFA step-up.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
max_slots_per_container integer no
max_containers_per_worker integer no
max_worker_containers_per_org integer no
idle_container_grace_seconds integer no
pool_floor_per_worker integer no

Responses

StatusDescription
200 Pool policy saved.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
GET /v1/helpdesk/pool-policy/get

Get container pool policy

Returns the organization's container pool policy (max slots, idle grace period, pool floor, etc.). Read-only; no MFA step-up required.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Pool policy.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/helpdesk/pool-status

Get live container pool status

Returns live per-virtual-worker container and slot occupancy. Optionally filtered by `virtual_worker_id`. SP self-gates on `support.read`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
virtual_worker_id query string<uuid> no Filter to a single virtual worker.

Responses

StatusDescription
200 Pool status.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/helpdesk/slot-config

Get container slot configuration

Returns the per-worker container slot count configuration.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Slot configuration.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/helpdesk/slot-config

Set container slot count for a worker

Configures the maximum number of concurrent container slots for a virtual worker (1–16). Requires MFA step-up.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
virtual_worker_id string<uuid> yes Virtual worker ID.
slot_count integer yes Maximum number of concurrent slots for this worker.

Responses

StatusDescription
200 Slot config saved.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
GET /v1/integrations/cloudflare/authorize

Get Cloudflare OAuth authorization URL

Returns the Cloudflare OAuth (PKCE) authorization URL. Accepts an optional `?purpose=` parameter (`dns` or `worker_sync`) to tailor the requested scopes. Feature-flag gated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
purpose query string (enum) no Intended use of the Cloudflare connection; influences requested scopes.

Responses

StatusDescription
200 Authorization URL and PKCE challenge generated.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
503 Cloudflare OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
url string<uri> The provider authorization URL to redirect the user to.
POST /v1/integrations/cloudflare/connect

Connect Cloudflare via authorization code

Completes the Cloudflare PKCE OAuth flow. Validates the CSRF `state` JWT, exchanges `code` for tokens, and stores the encrypted credential. Applies a scope-allowlist to prevent scope-confusion attacks. Feature-flag gated.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes OAuth authorization code from the provider.
state string yes CSRF state value from the authorize redirect.

Responses

StatusDescription
200 Cloudflare connection established.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 CSRF state validation failed. `error.code`: `AUTH_OAUTH_FAILED`.
503 Cloudflare OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
POST /v1/integrations/cloudflare/disconnect

Disconnect Cloudflare integration

Revokes and removes the stored Cloudflare OAuth credential for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Cloudflare integration disconnected.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/integrations/github/authorize

Get GitHub OAuth authorization URL

Returns the GitHub OAuth authorization URL the client should redirect the user to. The `state` is a signed CSRF JWT (HS256, 10-minute expiry) that must be round-tripped back to `/v1/integrations/github/callback`. Feature-flag gated; returns 503 when the GitHub OAuth application is not configured.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Authorization URL generated.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
503 GitHub OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
url string<uri> The provider authorization URL to redirect the user to.
GET /v1/integrations/github/callback

Handle GitHub OAuth callback

Completes the GitHub OAuth flow. Exchanges `code` for an access token, stores the encrypted credential, and returns the connection record. `state` is validated against the signed CSRF JWT issued by the authorize endpoint. Feature-flag gated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
code query string yes OAuth authorization code from GitHub.
state query string yes CSRF state value from the authorize redirect.

Responses

StatusDescription
200 GitHub connection created or updated.
400 Missing or invalid query parameters. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 CSRF state validation failed. `error.code`: `AUTH_OAUTH_FAILED`.
503 GitHub OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
id string<uuid> Connection record ID.
org_id string<uuid>
status string Connection status (e.g., `active`).
created_at string<date-time>
POST /v1/integrations/github/connect

Connect GitHub via authorization code

Exchanges a GitHub OAuth authorization code for a stored connection. Validates the `state` CSRF JWT, stores the encrypted OAuth token, and links the connection to the caller's organization. Feature-flag gated.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes OAuth authorization code from GitHub.
state string yes CSRF state value from the authorize redirect.

Responses

StatusDescription
200 GitHub connection established.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 CSRF state validation failed or feature disabled. `error.code`: `AUTH_OAUTH_FAILED` or `FEATURE_DISABLED`.
503 GitHub OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
id string<uuid> Connection record ID.
org_id string<uuid>
status string Connection status (e.g., `active`).
created_at string<date-time>
POST /v1/integrations/github/disconnect

Disconnect GitHub integration

Revokes the stored GitHub OAuth credential and removes the connection record for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 GitHub integration disconnected.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/integrations/github/repos

List accessible GitHub repositories

Returns repositories accessible via the caller's connected GitHub account. Feature-flag gated.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Repository list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
503 GitHub not connected or not configured. `error.code`: `SERVICE_UNAVAILABLE` or `PROVIDER_NOT_CONNECTED`.
200 response body: data fields
FieldTypeDescription
repos array of object
POST /v1/integrations/github/repos/attach

Attach a GitHub repository to the organization

Links a GitHub repository (identified by owner, name, and full name) to the caller's organization. Feature-flag gated.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
repoOwner string yes GitHub owner login.
repoName string yes GitHub repository name.
repoFullName string yes Full repository name (owner/repo).
defaultBranch string no Default branch name.
isPrivate boolean no Whether the repository is private.
githubRepoId integer no Numeric GitHub repository ID (optional).

Responses

StatusDescription
200 Repository attached.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
POST /v1/integrations/github/repos/detach

Detach a GitHub repository from the organization

Removes a previously linked GitHub repository from the caller's organization.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
repo_id string<uuid> yes ID of the repository attachment to remove.

Responses

StatusDescription
200 Repository detached.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/integrations/google/authorize

Get Google OAuth authorization URL

Returns the Google OAuth authorization URL. Accepts an optional `?products=` comma-separated list of Backbuild product keys to tailor the requested scopes. The `state` is a signed CSRF JWT. Feature-flag gated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
products query string no Comma-separated Backbuild product keys to scope the Google OAuth request.

Responses

StatusDescription
200 Authorization URL generated.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
503 Google OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
url string<uri> The provider authorization URL to redirect the user to.
POST /v1/integrations/google/connect

Connect Google via authorization code

Completes the Google OAuth flow. Validates the CSRF `state` JWT, exchanges `code` for tokens, and stores the encrypted credential. Feature-flag gated.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
code string yes OAuth authorization code from the provider.
state string yes CSRF state value from the authorize redirect.

Responses

StatusDescription
200 Google connection established.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 CSRF state validation failed. `error.code`: `AUTH_OAUTH_FAILED`.
503 Google OAuth not configured. `error.code`: `SERVICE_UNAVAILABLE`.
POST /v1/integrations/google/disconnect

Disconnect Google integration

Revokes and removes the stored Google OAuth credential for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Google integration disconnected.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/notifications

List notifications

Returns a paginated list of notifications for the authenticated user, optionally filtered by channel, type, read status, or time range. Supports `page`/`pageSize` pagination.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
page query integer no Page number (1-based).
pageSize query integer no Items per page.
channel query string (enum) no Filter by delivery channel.
notification_type query string (enum) no Filter by notification type.
is_read query string (enum) no Filter by read status.
since query string<date-time> no Return notifications created after this ISO timestamp.
until query string<date-time> no Return notifications created before this ISO timestamp.

Responses

StatusDescription
200 Notification list.
400 Invalid query parameters. `error.code`: `INVALID_PARAMETER`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 Database failure. `error.code`: `DATABASE_ERROR`.
200 response body: data fields
FieldTypeDescription
notifications array of object
pagination object Pagination metadata. Endpoints use either page/pageSize or limit/offset style; fields present depend on the endpoint.
POST /v1/notifications

Create a notification

Creates a notification for the caller or, with `notification.create` permission, for another user. `action_url` must be a Backbuild platform domain. Cross-user creation requires `notification.create` permission; otherwise `403 INSUFFICIENT_PERMISSIONS` is returned.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
title string yes Notification title.
body string no Optional notification body text.
notification_type string (enum) infosuccesswarningerroraction_required yes Semantic type of the notification.
channel string (enum) in_appemailpushslack no Delivery channel.
target_user_id string<uuid> no Target user; defaults to the caller. Creating for another user requires `notification.create` permission.
resource_type string no Type of the linked resource (e.g., `ticket`, `project`).
resource_id string<uuid> no ID of the linked resource.
action_url string<uri> no Call-to-action URL; must be a Backbuild platform domain.
priority string (enum) lownormalhighurgent no Delivery priority.
expires_at string<date-time> no Expiry timestamp; notification auto-hides after this.
metadata object no Bounded JSON metadata (max 32 KB).

Responses

StatusDescription
201 Notification created.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Cross-user notification without permission. `error.code`: `INSUFFICIENT_PERMISSIONS`.
500 Database failure. `error.code`: `DATABASE_ERROR`.
201 response body: data fields
FieldTypeDescription
id string<uuid>
title string
body string | null
notification_type string (enum) infosuccesswarningerroraction_required
channel string | null
is_read boolean
created_at string<date-time>
expires_at string | null
action_url string | null
PATCH /v1/notifications/{notificationId}

Mark a notification read/unread

Toggles the read status of a single notification. Only the notification's target user may update it.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
notificationId path string<uuid> yes Notification ID.

Request Body

FieldTypeRequiredDescription
is_read boolean yes Set to `true` to mark as read, `false` to mark as unread.

Responses

StatusDescription
200 Notification updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 Database failure. `error.code`: `DATABASE_ERROR`.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
body string | null
notification_type string (enum) infosuccesswarningerroraction_required
channel string | null
is_read boolean
created_at string<date-time>
expires_at string | null
action_url string | null
DELETE /v1/notifications/{notificationId}

Delete a notification

Permanently deletes a notification. Only the notification's target user may delete it.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
notificationId path string<uuid> yes Notification ID.

Responses

StatusDescription
200 Notification deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
500 Database failure. `error.code`: `DATABASE_ERROR`.
POST /v1/notifications/bulk-mark-read

Bulk mark notifications as read

Marks up to 100 notifications as read in a single operation. Only the caller's own notifications may be targeted.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
notification_ids array of string yes Array of notification IDs to mark as read.

Responses

StatusDescription
200 Notifications marked as read.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 Database failure. `error.code`: `DATABASE_ERROR`.
GET /v1/rdp/audit-log

List RDP audit log entries

Returns paginated RDP audit log entries. Requires `rdp.admin` permission. Supports cursor-based pagination (base64url-encoded JSON `{occurred_at, id}`) and optional filters. Response carries `Cache-Control: no-store`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
cursor query string no Pagination cursor (opaque base64url-encoded value).
limit query integer no Maximum results to return.
action query string no Filter by audit action name.
device_id query string<uuid> no Filter by device ID.
actor_user_id query string<uuid> no Filter by actor user ID.
session_id query string<uuid> no Filter by session ID.
since query string<date-time> no Return entries after this timestamp.
until query string<date-time> no Return entries before this timestamp.

Responses

StatusDescription
200 Audit log entries.
400 Invalid parameter or cursor. `error.code`: `INVALID_PARAMETER`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
POST /v1/rdp/audit-log/export

Export RDP audit log as CSV

Exports up to 5,000 RDP audit log entries as a CSV file. Supports the same filters as the list endpoint. CSV values are sanitized against formula-injection (OWASP). Requires `rdp.admin` permission.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
max_rows integer no Maximum rows to export (default 5000).
action string no
device_id string<uuid> no
actor_user_id string<uuid> no
session_id string<uuid> no
since string<date-time> no
until string<date-time> no

Responses

StatusDescription
200 CSV file attachment.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
GET /v1/rdp/devices

List registered RDP devices

Returns registered RDP devices for the caller's organization. Supports optional filters `include_inactive`, `host_only`, and `viewer_only`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
include_inactive query string (enum) no Include deregistered devices.
host_only query string (enum) no Return only host-capable devices.
viewer_only query string (enum) no Return only viewer-capable devices.

Responses

StatusDescription
200 Device list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/rdp/devices

Register an RDP device

Registers a device for use with remote desktop. The device submits its post-quantum identity bundle including KEM and signature algorithm IDs. Feature-flag gated for write operations.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
device_identifier string yes
device_name string yes
os_family string (enum) windowsmacoslinuxiosandroidwebother yes
os_version string yes
app_version string yes
capabilities object no Optional device capabilities (max 8 KB).
pq_kem_alg_id string yes Post-quantum KEM algorithm identifier.
pq_sig_alg_id string yes Post-quantum signature algorithm identifier.
pq_identity_bundle object yes Post-quantum identity bundle (max 32 KB).

Responses

StatusDescription
201 Device registered.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Feature not enabled. `error.code`: `FEATURE_DISABLED`.
DELETE /v1/rdp/devices/{deviceId}

Deregister an RDP device

Removes a device from the RDP registry. Feature-flag gated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
deviceId path string<uuid> yes Device ID.

Responses

StatusDescription
200 Device deregistered.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Feature not enabled. `error.code`: `FEATURE_DISABLED`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/rdp/devices/{hostId}/trust

Grant viewer trust to a host device

Grants a viewer device permission to connect to the specified host device, binding the trust to an expected public-key hash. Feature-flag gated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
hostId path string<uuid> yes Host device ID.

Request Body

FieldTypeRequiredDescription
viewer_device_id string<uuid> yes
expected_pubkey_hash string yes Hash of the viewer's expected public key.
permissions object yes Permission set granted to the viewer (max 4 KB).

Responses

StatusDescription
200 Trust granted.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Feature not enabled. `error.code`: `FEATURE_DISABLED`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 Public key mismatch detected. `error.code`: `PUBKEY_MISMATCH`.
DELETE /v1/rdp/devices/{hostId}/trust

Revoke viewer trust from a host device

Removes a viewer device's trust relationship with a host device.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
hostId path string<uuid> yes Host device ID.

Request Body

FieldTypeRequiredDescription
viewer_device_id string<uuid> yes Viewer device to untrust.

Responses

StatusDescription
200 Trust revoked.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/rdp/my-data-export

Export the caller's RDP data (GDPR Art. 15)

Returns all RDP device registrations, sessions, and audit events for the authenticated caller. GDPR Article 15 self-service data access. Response carries `Cache-Control: no-store, private`.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
since query string<date-time> no Export data after this timestamp.
until query string<date-time> no Export data before this timestamp.
max_rows query integer no Maximum number of records to include.

Responses

StatusDescription
200 Caller's RDP data export.
400 Invalid parameter. `error.code`: `INVALID_PARAMETER`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/rdp/my-data-forget

Erase the caller's RDP data (GDPR Art. 17)

Pseudonymizes or deletes the caller's RDP device registrations, sessions, and audit records. GDPR Article 17 self-service erasure. Optionally scoped to a single organization.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
org_id string<uuid> no Optional: scope erasure to a single organization.

Responses

StatusDescription
200 Erasure completed.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/rdp/sessions

Authorize an RDP session

Creates and authorizes a remote desktop session between a host and viewer device. Validates the post-quantum algorithm negotiation. Returns `409 CRYPTO_FLOOR_VIOLATION` (HTTP 426 Upgrade Required) if the negotiated cipher suites fall below the organization's security floor.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
host_device_id string<uuid> yes
viewer_device_id string<uuid> yes
viewer_user_id string<uuid> yes
viewer_pubkey_hash string yes
signaling_session_id string yes
kem_alg_negotiated string yes
sig_alg_negotiated string yes
aead_alg_negotiated string yes

Responses

StatusDescription
201 Session authorized.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `PERMISSION_DENIED`.
426 Negotiated cipher suite below org security floor. `error.code`: `CRYPTO_FLOOR_VIOLATION`.
DELETE /v1/rdp/sessions/{sessionId}

End an RDP session

Terminates an active RDP session, recording the end reason and final byte counters.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Request Body

FieldTypeRequiredDescription
end_reason string yes
ice_connection_type string no
total_bytes_in integer no
total_bytes_out integer no

Responses

StatusDescription
200 Session ended.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/rdp/sessions/{sessionId}/consent

Poll session consent status (viewer)

Returns the current host consent status for a session. Used by the viewer to poll whether the host has granted or denied access. Includes seconds remaining in the consent window.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Responses

StatusDescription
200 Consent status.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Caller is not a session participant. `error.code`: `FORBIDDEN`.
POST /v1/rdp/sessions/{sessionId}/consent

Respond to a session consent request (host)

Host grants or denies a pending viewer connection. The session's `host_consent_status` transitions to `granted` or `denied`. Returns `409` with `consent_already_decided` if a decision was already made, or `410` with `session_ended` if the session is terminated.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Request Body

FieldTypeRequiredDescription
decision string (enum) granteddenied yes Host consent decision.

Responses

StatusDescription
200 Consent decision recorded.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Caller is not the session host. `error.code`: `FORBIDDEN`.
409 Consent already decided. `error.code`: `consent_already_decided`.
410 Session has ended. `error.code`: `session_ended`.
GET /v1/rdp/sessions/{sessionId}/diagnostics

Get RDP session diagnostics

Returns session diagnostics including ICE connection stats and byte counters. Accessible by session participants and admins.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Responses

StatusDescription
200 Session diagnostics.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Not a session participant or admin. `error.code`: `FORBIDDEN`.
POST /v1/rdp/sessions/{sessionId}/heartbeat

Send a session heartbeat

Keeps a session alive and records incremental byte counters. TURN relay usage is attributed from the canonical ICE connection type recorded by the server, not the client-supplied value.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Request Body

FieldTypeRequiredDescription
ice_connection_type string no ICE connection type (e.g., `relay`, `srflx`, `host`).
bytes_in_delta integer yes Bytes received since last heartbeat.
bytes_out_delta integer yes Bytes sent since last heartbeat.

Responses

StatusDescription
200 Heartbeat recorded.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/rdp/sessions/{sessionId}/signaling-token

Issue a WebRTC signaling token

Issues an HMAC-signed one-time signaling token for joining the RDP signaling DO. The token encodes the caller's role (`host` or `viewer`), a unique `jti`, and the DO session ID. Returns `403 CONSENT_PENDING` if the host has not yet responded to the consent prompt, or `403 CONSENT_DENIED` if access was denied.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Request Body

FieldTypeRequiredDescription
role string (enum) hostviewer yes The role the caller will play in the signaling session.

Responses

StatusDescription
200 Signaling token issued.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Consent pending or denied. `error.code`: `CONSENT_PENDING` or `CONSENT_DENIED`.
200 response body: data fields
FieldTypeDescription
token string Signed signaling token.
expires_at string<date-time>
do_session_id string Durable Object session ID.
ws_url string WebSocket upgrade path for the signaling connection.
POST /v1/rdp/sessions/{sessionId}/turn-credentials

Issue TURN relay credentials

Issues RFC 5766 TURN credentials for the session. Checks the per-org 24-hour bandwidth quota (fail-closed); returns `429 quota_exceeded` if exhausted. Credentials are bound to the caller's user ID and source IP — mismatched heartbeats will not attribute relay bytes to prevent credential-sharing abuse.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
sessionId path string<uuid> yes Session ID.

Responses

StatusDescription
200 TURN credentials.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Org context missing. `error.code`: `FORBIDDEN`.
429 24-hour TURN bandwidth quota exceeded. `error.code`: `quota_exceeded`.
503 TURN quota DO unreachable or relay not configured. `error.code`: `INTERNAL_ERROR` or `SERVICE_UNAVAILABLE`.
200 response body: data fields
FieldTypeDescription
username string TURN username (bound to expiry, session, user, and IP).
credential string HMAC-derived TURN credential.
ttl integer Credential TTL in seconds.
uris array of string TURN server URIs (`turn:` or `turns:` scheme only).
GET /v1/rdp/signal/{doSessionId}

Upgrade to WebRTC signaling WebSocket

Upgrades the connection to a WebSocket for WebRTC signaling. The caller must present a valid HMAC-signed signaling token via the `?token=` query parameter, the `X-RDP-Signaling-Token` header, or the `X-RDP-Token` header. The token must be bound to the requested `doSessionId`. Returns `426` if the `Upgrade: websocket` header is absent.

Auth One-time ?token= ticket

Parameters

NameInTypeRequiredDescription
doSessionId path string yes Durable Object signaling session ID (org-scoped: `<orgId>:<signalingSessionId>`).
token query string no HMAC-signed signaling token (alternative to header).

Responses

StatusDescription
101 WebSocket upgrade accepted; signaling session established.
400 Invalid session ID format. `error.code`: `INVALID_ID_FORMAT`.
401 Missing, invalid, or expired signaling token. `error.code`: `UNAUTHORIZED`.
426 WebSocket upgrade header missing. `error.code`: `VALIDATION_ERROR`.
GET /v1/rdp/turn-quota

Get TURN relay bandwidth quota

Returns the organization's current TURN relay bandwidth usage within the rolling 24-hour window. Requires `rdp.admin` permission.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 TURN quota status.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
200 response body: data fields
FieldTypeDescription
bytes_used_24h integer Bytes used in the rolling 24-hour window.
bytes_cap integer Per-org 24-hour byte cap.
issuances_24h integer Number of TURN credential issuances in the window.
window_ms integer Window duration in milliseconds.
window_started_at integer Window start timestamp (Unix ms).
GET /v1/secrets/admin-recovery/{targetUserId}

Get admin recovery materials for a user

Returns the recovery materials needed to re-seal a user's secrets identity during an admin-initiated password reset. Requires `org.manage_members` or `secrets.recover` permission and MFA step-up.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
targetUserId path string<uuid> yes Target user ID.

Responses

StatusDescription
200 Recovery materials.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions or MFA step-up required. `error.code`: `PERMISSION_DENIED` or `MFA_STEPUP_REQUIRED`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/secrets/admin-recovery/{targetUserId}/reset

Reset a user's secrets vault (admin recovery)

Re-seals a user's secrets identity with a new sealed private-key blob. Used to reset access when the user has lost their master password. Requires `org.manage_members` or `secrets.recover` permission and MFA step-up. The new `kdf` parameters must meet the platform floor.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
targetUserId path string<uuid> yes Target user ID.

Request Body

FieldTypeRequiredDescription
sealedPrivBlob string yes
saltUser string yes
kdf object yes Argon2 KDF parameters. Must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.

Responses

StatusDescription
200 Identity reset.
400 Validation error or KDF below floor. `error.code`: `VALIDATION_ERROR` or `CRYPTO_FLOOR_VIOLATION`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions or MFA step-up required. `error.code`: `PERMISSION_DENIED` or `MFA_STEPUP_REQUIRED`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/ai/vaults

List vault metadata (AI-accessible)

Returns vault names and types for the caller's organization. No ciphertext or key material is ever included. Intended for AI agents to enumerate available vaults without decrypting content.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Vault metadata list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/secrets/ai/vaults/{vaultId}/items

List vault item metadata (AI-accessible)

Returns item names, types, and field names for a vault — never ciphertext or decrypted values. Intended for AI agents to discover available secret slots.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Responses

StatusDescription
200 Item metadata list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/identity

Get secrets identity for the caller

Returns the caller's encrypted secrets identity blob (sealed private key, salt, KDF parameters). Used by the client to re-derive the vault key without reinitializing.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Secrets identity blob.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 Identity not initialized. `error.code`: `NOT_FOUND`.
200 response body: data fields
FieldTypeDescription
sealedPrivBlob string
saltUser string
kdf object Argon2 KDF parameters. Must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.
pubKey string
POST /v1/secrets/init

Initialize the secrets vault for a user

One-time initialization that creates the caller's zero-knowledge identity in the secrets vault. Requires MFA step-up and MFA verification. Rate-limited to 5 requests per 15 minutes per user/IP. The `kdf` parameters must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
sealedPrivBlob string yes Encrypted private-key blob.
saltUser string yes User-specific KDF salt.
kdf object yes Argon2 KDF parameters. Must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.
pubKey string yes Public key for vault key wrapping.

Responses

StatusDescription
200 Vault initialized.
400 Validation error or KDF below floor. `error.code`: `VALIDATION_ERROR` or `CRYPTO_FLOOR_VIOLATION`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
POST /v1/secrets/lock

Lock the secrets vault session

Invalidates the current secrets session, clearing the vault unlock state.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Vault locked.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
PUT /v1/secrets/master-password

Change the master password

Re-wraps the sealed private-key blob with a new KDF-derived key. Requires MFA step-up and MFA verification. Rate-limited to 12 requests per minute. The new `kdf` parameters must meet the platform KDF floor.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
sealedPrivBlob string yes
saltUser string yes
kdf object yes Argon2 KDF parameters. Must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.

Responses

StatusDescription
200 Master password changed.
400 Validation error or KDF below floor. `error.code`: `VALIDATION_ERROR` or `CRYPTO_FLOOR_VIOLATION`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
DELETE /v1/secrets/purge

Purge the caller's secrets identity

Permanently deletes the caller's zero-knowledge secrets identity and all associated vault memberships. Irreversible. Requires MFA step-up and MFA verification.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Identity purged.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
GET /v1/secrets/server-escrow-pubkey

Get server escrow public key

Returns the server's KEM public key used to wrap the vault key for VW (Virtual Worker) vaults. Enables placeholder substitution without exposing human-vault ciphertext.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Server escrow public key.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
500 Escrow key unavailable. `error.code`: `INTERNAL_ERROR`.
200 response body: data fields
FieldTypeDescription
kemPublic string Base64-encoded KEM public key.
POST /v1/secrets/substitute

Substitute secret placeholders in text

Resolves `{{secret:<vaultId>/<itemId>/<field>}}` placeholders in the provided text with their decrypted values from VW (Virtual Worker) vaults. Human ZK vaults are never server-decryptable and their placeholders are left intact. Requires `secrets.substitute` scope (container/VW token). The returned text is never logged or re-stored by the server. Input text must be ≤ 100,000 characters.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
text string yes Input text containing `{{secret:...}}` placeholders to resolve.

Responses

StatusDescription
200 Text with placeholders resolved.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
200 response body: data fields
FieldTypeDescription
text string Text with resolved placeholders.
substituted integer Number of placeholders successfully resolved.
GET /v1/secrets/sync/bindings

List secret sync bindings

Returns sync bindings for a vault (and optionally a specific item). Requires `vaultId` (UUID) as a query parameter; callers without vault membership receive 404. Any vault member may read bindings; write operations require manager or owner role.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId query string<uuid> yes Vault ID (required; membership-gates the listing).
itemId query string<uuid> no Narrow results to a specific vault item.

Responses

StatusDescription
200 Binding list.
400 Validation error or missing vaultId. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 Vault not found or caller is not a member. `error.code`: `NOT_FOUND`.
POST /v1/secrets/sync/bindings

Create or update a secret sync binding

Creates or updates a binding that maps a vault item field to a provider destination (e.g., a Cloudflare Workers secret). Requires vault manager or owner role and MFA step-up. The `connectionId` must be the caller's own active connection for the provider. The `locator` must lie within the connection's pinned scope (TOCTOU-validated).

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
id string<uuid> no Existing binding ID for update; omit to create.
vaultId string<uuid> yes
itemId string<uuid> yes
fieldPath string yes Field path within the vault item.
provider string yes Provider key (e.g., `cloudflare`).
connectionId string<uuid> yes Must be the caller's own active connection for this provider.
locator object yes Provider-specific destination locator (e.g., Worker script name).
destSecretName string yes Destination secret name at the provider.
generatable boolean no
overlapEnabled boolean no
rotateEverySeconds integer no

Responses

StatusDescription
200 Binding created or updated.
400 Validation or locator scope error. `error.code`: `VALIDATION_ERROR`, `PROVIDER_UNAVAILABLE`, or `LOCATOR_SCOPE`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required, insufficient vault role, or connection mismatch. `error.code`: `MFA_STEPUP_REQUIRED`, `FORBIDDEN`, or `PROVIDER_NOT_CONNECTED`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 409 Conflict — the request conflicts with an existing resource or current state (unique constraint, optimistic-lock, duplicate).
DELETE /v1/secrets/sync/bindings/{bindingId}

Delete a secret sync binding

Soft-deletes a sync binding. Requires vault manager or owner role and MFA step-up.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
bindingId path string<uuid> yes Binding ID.

Responses

StatusDescription
200 Binding deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required or insufficient vault role. `error.code`: `MFA_STEPUP_REQUIRED` or `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/sync/cloudflare/scripts

List Cloudflare Workers scripts

Returns script names from the connected Cloudflare account for use as sync binding targets. Returns an empty list if not connected or lacking `workers:read` scope.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Script name list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/secrets/sync/providers

List secret sync providers

Returns available secret sync providers (e.g., Cloudflare Workers Secrets) and the caller's connection status for each. No secret values are included.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Provider list with connection status.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/secrets/sync/push

Push secret field values to external providers

Sends client-decrypted field values to their configured external provider destinations (Mode A interactive sync). Each binding is processed independently — one failure does not stop others. The `value` field is write-only: it is never logged, audited, or returned. Requires vault manager or owner role and MFA step-up. Up to 50 syncs per request.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
vaultId string<uuid> yes
itemId string<uuid> yes
syncs array of object yes

Responses

StatusDescription
200 Sync results per binding.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required or insufficient vault role. `error.code`: `MFA_STEPUP_REQUIRED` or `FORBIDDEN`.
200 response body: data fields
FieldTypeDescription
results array of object
GET /v1/secrets/trash

List trashed vault items

Returns all items in the caller's trash across their vaults.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Trash item list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/secrets/trash/{itemId}/restore

Restore a trashed vault item

Restores a previously trashed vault item back to its vault.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
itemId path string<uuid> yes Trashed item ID.

Responses

StatusDescription
200 Item restored.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
DELETE /v1/secrets/trash/empty

Empty the trash

Permanently deletes all trashed vault items. Requires MFA step-up.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Trash emptied.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
POST /v1/secrets/unlock

Unlock the secrets vault session

Authenticates the caller's zero-knowledge vault session using their sealed private-key blob. Returns an encrypted session token. Requires MFA step-up and MFA verification. Rate-limited to 12 requests per minute per user/IP. On failure always returns 401 with no oracle information.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
sealedPrivBlob string yes Encrypted private-key blob.
saltUser string yes User-specific KDF salt.
kdf object yes Argon2 KDF parameters. Must meet the platform floor: `mem_kib` ≥ 19456, `iters` ≥ 2.

Responses

StatusDescription
200 Vault unlocked; encrypted session token returned.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 Authentication required or unlock failed. `error.code`: `UNAUTHORIZED` or `AUTH_REQUIRED`.
403 MFA step-up required. `error.code`: `MFA_STEPUP_REQUIRED`.
429 429 Too Many Requests — a rate limit or usage quota was exceeded. Retry after the indicated window.
200 response body: data fields
FieldTypeDescription
sessionToken string Encrypted secrets session token.
expiresAt string<date-time>
GET /v1/secrets/vaults

List secrets vaults

Returns all vaults the caller is a member of within the active environment. Only metadata is returned — no ciphertext.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Vault list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
200 response body: data fields
FieldTypeDescription
vaults array of object
POST /v1/secrets/vaults

Create a secrets vault

Creates a new secrets vault in the active environment. Vaults are zero-knowledge by default; a `virtual_worker` vault also carries a server-escrow key wrap for automated substitution.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
description string no
type string (enum) personalteamvirtual_worker yes Vault type. `virtual_worker` vaults carry a server-escrow key wrap.
sealedVaultKey string yes Vault key sealed to the creator's public key.
serverEscrowWrap string no Vault key wrapped to the server escrow KEM public key (required for `virtual_worker` type).

Responses

StatusDescription
201 Vault created.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
201 response body: data fields
FieldTypeDescription
id string<uuid>
name string
type string
created_at string<date-time>
role string Caller's role in this vault.
GET /v1/secrets/vaults/{vaultId}

Get vault metadata

Returns metadata for a specific vault. Membership is required to access the vault. No ciphertext is returned.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Responses

StatusDescription
200 Vault metadata.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
name string
type string
created_at string<date-time>
role string Caller's role in this vault.
PATCH /v1/secrets/vaults/{vaultId}

Update vault metadata

Updates the name or description of a vault. Requires vault owner or manager role.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Request Body

FieldTypeRequiredDescription
name string no Vault display name.
description string no Optional vault description.

Responses

StatusDescription
200 Vault updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient vault role. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
name string
type string
created_at string<date-time>
role string Caller's role in this vault.
DELETE /v1/secrets/vaults/{vaultId}

Delete a vault

Permanently deletes a vault and all its encrypted items. Requires vault owner role. Requires MFA step-up.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Responses

StatusDescription
200 Vault deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 MFA step-up required or insufficient vault role. `error.code`: `MFA_STEPUP_REQUIRED` or `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/vaults/{vaultId}/items

List vault items (metadata only)

Returns item metadata for all items in a vault. The server never returns ciphertext from the AI-accessible metadata endpoint — only name, type, created-at, and tags.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Responses

StatusDescription
200 Item metadata list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/secrets/vaults/{vaultId}/items

Create a vault item

Stores an encrypted vault item. The encrypted content blob is passed through opaque — the server never decrypts it. Requires vault membership.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Request Body

FieldTypeRequiredDescription
name string yes Item display name.
type string yes Item type (e.g., `login`, `note`, `api_key`).
encContent string yes Encrypted item content blob (opaque to server).
itemSalt string yes Per-item salt for AAD derivation.
tags array of string no Optional searchable tags.

Responses

StatusDescription
201 Item created.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Not a vault member. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/vaults/{vaultId}/items/{itemId}

Get an encrypted vault item

Returns the encrypted content blob for a vault item. Only vault members may retrieve items. The server does not decrypt the content.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.
itemId path string<uuid> yes Item ID.

Responses

StatusDescription
200 Encrypted item.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Not a vault member. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
PUT /v1/secrets/vaults/{vaultId}/items/{itemId}

Update a vault item

Replaces the encrypted content blob of an existing vault item. Requires vault membership.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.
itemId path string<uuid> yes Item ID.

Request Body

FieldTypeRequiredDescription
name string yes Item display name.
type string yes Item type (e.g., `login`, `note`, `api_key`).
encContent string yes Encrypted item content blob (opaque to server).
itemSalt string yes Per-item salt for AAD derivation.
tags array of string no Optional searchable tags.

Responses

StatusDescription
200 Item updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Not a vault member. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
DELETE /v1/secrets/vaults/{vaultId}/items/{itemId}

Delete a vault item

Moves an item to the trash. Requires vault membership.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.
itemId path string<uuid> yes Item ID.

Responses

StatusDescription
200 Item moved to trash.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Not a vault member. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/secrets/vaults/{vaultId}/members

List vault members

Returns the membership list for a vault. Only vault members may view this list. Non-human members cannot be added.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Responses

StatusDescription
200 Vault member list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/secrets/vaults/{vaultId}/members

Add a member to a vault

Adds a user to a vault with an assigned role (`member`, `manager`, or `owner`). Requires vault manager or owner role. Non-human accounts cannot be added (`403 TARGET_NOT_ELIGIBLE`).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.

Request Body

FieldTypeRequiredDescription
user_id string<uuid> yes User to add.
role string (enum) membermanagerowner yes Vault role.
sealed_vault_key string yes Client-encrypted vault key sealed to the new member's public key.

Responses

StatusDescription
200 Member added.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Non-human target or insufficient role. `error.code`: `TARGET_NOT_ELIGIBLE` or `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
DELETE /v1/secrets/vaults/{vaultId}/members/{userId}

Remove a member from a vault

Removes a user from a vault. Requires vault manager or owner role.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
vaultId path string<uuid> yes Vault ID.
userId path string<uuid> yes User ID to remove.

Responses

StatusDescription
200 Member removed.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient vault role. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/themes

List themes

Returns all themes available to the caller's organization, including system themes and custom org themes.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Theme list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
200 response body: data fields
FieldTypeDescription
themes array of object
POST /v1/themes

Create a theme

Creates a new custom theme. The request must include either `theme_data` (a complete theme object) or all three of `colors`, `typography`, and `layout`. The `name` is required and must be 1–255 characters.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes Theme display name.
description string no
is_dark boolean no
is_default boolean no
status string (enum) activedraftarchived no
colors object no Color token map.
typography object no Typography token map.
layout object no Layout token map.
theme_data object no Complete theme data object (alternative to colors+typography+layout).

Responses

StatusDescription
201 Theme created.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
201 response body: data fields
FieldTypeDescription
id string<uuid>
name string
status string (enum) activedraftarchived
is_dark boolean
is_default boolean
created_at string<date-time>
GET /v1/themes/{themeId}

Get a theme

Returns the full definition of a theme by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
themeId path string<uuid> yes Theme ID.

Responses

StatusDescription
200 Theme details.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
name string
status string (enum) activedraftarchived
is_dark boolean
is_default boolean
created_at string<date-time>
PUT /v1/themes/{themeId}

Update a theme

Replaces a theme's definition. Only custom org themes may be modified. The same `theme_data` vs `colors+typography+layout` rule applies as on create.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
themeId path string<uuid> yes Theme ID.

Request Body

FieldTypeRequiredDescription
name string yes Theme display name.
description string no
is_dark boolean no
is_default boolean no
status string (enum) activedraftarchived no
colors object no Color token map.
typography object no Typography token map.
layout object no Layout token map.
theme_data object no Complete theme data object (alternative to colors+typography+layout).

Responses

StatusDescription
200 Theme updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Attempting to modify a system theme. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
409 Duplicate theme name. `error.code`: `CONFLICT`.
200 response body: data fields
FieldTypeDescription
id string<uuid>
name string
status string (enum) activedraftarchived
is_dark boolean
is_default boolean
created_at string<date-time>
GET /v1/tickets

List support tickets

Returns a paginated list of helpdesk tickets for the caller's organization. Supports limit/offset pagination and optional status/priority filters.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
limit query integer no Maximum number of records to return. Default and ceiling are endpoint-specific (commonly default 25–50, max 100).
offset query integer no Number of records to skip for offset pagination.
status query string (enum) no Filter by ticket status.
priority query string (enum) no Filter by ticket priority.

Responses

StatusDescription
200 Ticket list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
200 response body: data fields
FieldTypeDescription
tickets array of object
pagination object Pagination metadata. Endpoints use either page/pageSize or limit/offset style; fields present depend on the endpoint.
POST /v1/tickets

Create a support ticket

Creates a new helpdesk support ticket. Request body is capped at 768 KB. An optional `repro` object attaches a structured issue-reproduction recording to the ticket.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
title string yes Ticket title.
body string no Initial ticket description (up to 100,000 characters).
saas_package_id string no SaaS package ID (hex UUID format) to scope the ticket.
category string no Category key.
priority string (enum) lownormalhighurgent no Ticket priority.
source string (enum) webchatapi no Origin channel.
context object no Arbitrary JSON context object (max 32 KB).
repro object no Optional structured issue-reproduction recording.

Responses

StatusDescription
201 Ticket created.
400 Validation error. `error.code`: `VALIDATION_ERROR` or `INVALID_JSON`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
413 Request body exceeds the 768 KB limit. `error.code`: `PAYLOAD_TOO_LARGE`.
201 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
GET /v1/tickets/{ticketId}

Get a support ticket

Returns full ticket details including messages and metadata.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Responses

StatusDescription
200 Ticket details.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
PATCH /v1/tickets/{ticketId}

Update a support ticket

Updates mutable ticket fields (priority, category). All fields are optional.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
priority string (enum) lownormalhighurgent no
category string no

Responses

StatusDescription
200 Ticket updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
GET /v1/tickets/{ticketId}/agent

Get full ticket details (agent view)

Returns full ticket details including internal messages and agent metadata. Intended for helpdesk agents.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Responses

StatusDescription
200 Full ticket (agent view).
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
403 Insufficient permissions. `error.code`: `FORBIDDEN`.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
PATCH /v1/tickets/{ticketId}/assign

Assign a ticket

Assigns a ticket to a human agent, AI agent, virtual worker, or unassigns it.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
assignee_kind string (enum) humanagentvirtual_workerunassigned yes Type of assignee.
assignee_id string<uuid> no ID of the assignee. Required unless `assignee_kind` is `unassigned`.

Responses

StatusDescription
200 Ticket assigned.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
POST /v1/tickets/{ticketId}/csat

Submit CSAT rating for a ticket

Records a customer satisfaction score (1–5) and optional comment for a resolved or closed ticket.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
score integer yes CSAT score from 1 (very dissatisfied) to 5 (very satisfied).
comment string no Optional free-text comment.

Responses

StatusDescription
200 CSAT recorded.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/tickets/{ticketId}/merge

Merge a ticket into another

Merges this ticket into a target ticket identified by `target_id`. The source ticket is closed after merging.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID to merge from.

Request Body

FieldTypeRequiredDescription
target_id string<uuid> yes ID of the ticket to merge into.

Responses

StatusDescription
200 Tickets merged.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
POST /v1/tickets/{ticketId}/messages

Add a message to a ticket

Appends a message to an existing ticket. Supports `text` and `latex` body formats. Attachments can reference documents or sheets by ID. Up to 10 attachments are allowed.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
body string yes Message body.
visibility string (enum) publicinternal no Message visibility; `internal` is only visible to agents.
body_format string (enum) textlatex no Formatting hint for the message body.
attachments array of object no

Responses

StatusDescription
201 Message added.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/tickets/{ticketId}/repro

Get ticket issue-reproduction recording

Returns the structured issue-reproduction recording (ZA appendix) attached to the ticket at creation.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Responses

StatusDescription
200 Reproduction recording.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
PATCH /v1/tickets/{ticketId}/snooze

Snooze or unsnooze a ticket

Sets or clears the snooze time on a ticket. Pass `snooze_until: null` to unsnooze.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
snooze_until string | null no ISO 8601 timestamp to snooze until, or `null` to unsnooze.

Responses

StatusDescription
200 Snooze updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
POST /v1/tickets/{ticketId}/status

Update ticket status

Transitions a ticket to a new status.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Request Body

FieldTypeRequiredDescription
status string (enum) opentriagein_progresswaiting_customerresolvedclosed yes New ticket status.

Responses

StatusDescription
200 Status updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
200 response body: data fields
FieldTypeDescription
id string<uuid>
title string
status string (enum) opentriagein_progresswaiting_customerresolvedclosed
priority string (enum) lownormalhighurgent
category string | null
created_at string<date-time>
updated_at string<date-time>
POST /v1/tickets/{ticketId}/watch

Toggle watching a ticket

Toggles the caller's watch status on a ticket (watch/unwatch).

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Responses

StatusDescription
200 Watch status toggled.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/tickets/{ticketId}/watchers

Get ticket watchers

Returns the list of users watching this ticket.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ticketId path string<uuid> yes Ticket ID.

Responses

StatusDescription
200 Watcher list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/tickets/attach-documents

Search documents attachable to a ticket

Returns a list of documents accessible to the caller that can be attached to a ticket message. Supports optional `q` search parameter.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
q query string no Search query to filter documents.

Responses

StatusDescription
200 Attachable document list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/tickets/canned-responses

List canned responses

Returns saved canned responses for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Canned response list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/tickets/canned-responses

Create a canned response

Creates a new canned response for use in ticket replies.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
name string yes
body string yes
category_key string no

Responses

StatusDescription
201 Canned response created.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
DELETE /v1/tickets/canned-responses/{cannedId}

Delete a canned response

Deletes a saved canned response by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
cannedId path string<uuid> yes Canned response ID.

Responses

StatusDescription
200 Canned response deleted.
400 Invalid ID format. `error.code`: `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/tickets/categories

List ticket categories

Returns the ticket category taxonomy for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Category list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/tickets/categories

Create a ticket category

Creates a new ticket category.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
key string yes
label string yes
description string no
parent_key string no

Responses

StatusDescription
201 Category created.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
DELETE /v1/tickets/categories/{categoryId}

Delete a ticket category

Deletes a ticket category by ID.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
categoryId path string<uuid> yes Category ID.

Responses

StatusDescription
200 Category deleted.
400 Invalid ID format. `error.code`: `INVALID_ID_FORMAT`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
GET /v1/tickets/mine

List the caller's own tickets

Returns tickets submitted by the authenticated user.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
limit query integer no Maximum number of tickets to return.

Responses

StatusDescription
200 Caller's ticket list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/tickets/requester-categories

List ticket categories for requesters

Returns the categories visible to a requester when filing a ticket. Supports optional `saas_package_id` filter.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
saas_package_id query string no SaaS package scope.

Responses

StatusDescription
200 Requester category list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
GET /v1/tickets/routing-rules

List ticket routing rules

Returns all routing rules defined for the caller's organization.

Auth Session JWT (Bearer)

Responses

StatusDescription
200 Routing rule list.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
POST /v1/tickets/routing-rules

Create a ticket routing rule

Creates a new routing rule for automatic ticket assignment based on category and priority.

Auth Session JWT (Bearer)

Request Body

FieldTypeRequiredDescription
category_key string yes Category to match.
priority string (enum) lownormalhighurgent no
assignee_kind string (enum) humanagentvirtual_worker yes
assignee_id string<uuid> no
is_enabled boolean no

Responses

StatusDescription
201 Routing rule created.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
PUT /v1/tickets/routing-rules/{ruleId}

Update a ticket routing rule

Replaces a routing rule definition.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Routing rule ID.

Request Body

FieldTypeRequiredDescription
category_key string yes Category to match.
priority string (enum) lownormalhighurgent no
assignee_kind string (enum) humanagentvirtual_worker yes
assignee_id string<uuid> no
is_enabled boolean no

Responses

StatusDescription
200 Routing rule updated.
400 Validation error. `error.code`: `VALIDATION_ERROR`.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.
DELETE /v1/tickets/routing-rules/{ruleId}

Delete a ticket routing rule

Deletes an existing ticket routing rule.

Auth Session JWT (Bearer)

Parameters

NameInTypeRequiredDescription
ruleId path string<uuid> yes Routing rule ID.

Responses

StatusDescription
200 Routing rule deleted.
401 401 Unauthorized — missing, expired, malformed, or revoked credentials.
404 404 Not Found — the requested resource does not exist or is not visible to the caller.