| read_when |
|
|---|
packages/protocol/openapi.yaml is the API contract source of truth. Server
handlers live in apps/api/internal/httpapi; the TypeScript SDK in
packages/sdk-ts is the typed client.
The server resolves callers in this order (see ../features/auth.md):
Authorization: Bearer <token>(session token, magic-link result).- Session cookie (
cc_sessionby default, or the configured namespaced name). X-ClickClack-User: usr_...header (local/dev impersonation for tests).- Dev fallback to the first user in the DB (only with
--dev-bootstrap=true).
/healthz, /readyz, and the opt-in /metrics operator endpoint do not use
chat authentication. Keep metrics private. Every HTTP response carries
X-Correlation-ID; a caller-supplied value is accepted only when it uses the
safe bounded character set. Durable message.created and
thread.reply_created events copy that validated value to optional
payload.correlation_id metadata for HTTP recovery and WebSocket consumers.
The value is not stored on message rows or exported as a metrics label.
| Group | Endpoints | Doc |
|---|---|---|
| Auth | /api/auth/magic/{request,consume}, /api/auth/github/{start,callback} |
auth |
| Profile | /api/me, /api/me/bots |
profiles |
| Workspaces | /api/workspaces, /api/workspaces/{id}, /api/workspaces/{id}/members |
workspaces |
| Moderation | /api/workspaces/{id}/moderation/members |
moderation |
| Bots | /api/workspaces/{id}/{bots,bot-commands}, /api/workspaces/{id}/bots/{bot_id}/{tokens,membership,setup-codes}, /api/bots/{id}, /api/bots/{id}/tokens, /api/bots/self/commands, /api/bot-tokens/{id}/revoke, /api/bot-setup-codes/claim |
bots |
| Event types | /api/event-types |
integrations |
| App installs | /api/workspaces/{id}/app-installations, /api/app-installations/{id}/revoke |
integrations |
| Slash commands | /api/workspaces/{id}/slash-commands, /api/slash-commands/{id}/{revoke,rotate-secret}, /api/hooks/slash/{channel} |
integrations |
| Event subscriptions | /api/workspaces/{id}/event-subscriptions, /api/event-subscriptions/{id}/{revoke,rotate-secret,deliveries} |
integrations |
| Audit log | /api/workspaces/{id}/audit-log |
integrations |
| Connected accounts | /api/workspaces/{id}/connected-accounts, /api/connected-accounts/{id}/revoke |
integrations |
| Topics | /api/workspaces/{id}/topics |
messages |
| Channels | /api/workspaces/{id}/channels, /api/channels/{id} |
workspaces |
| Messages | /api/channels/{id}/messages, /api/messages/by-nonce, /api/messages/{id} |
messages |
| Threads | /api/messages/{id}/thread, /api/messages/{id}/thread/replies |
threads |
| Replies | quoted_message_id on any message-create endpoint |
replies |
| Reactions | /api/messages/{id}/reactions |
reactions |
| Realtime | /api/realtime/{ws,events,ephemeral} |
realtime |
| Search | /api/search |
search |
| Uploads | /api/uploads, /api/uploads/by-nonce, /api/messages/{id}/attachments |
uploads |
| DMs | /api/dms, /api/dms/{id}, /api/dms/{id}/open, /api/dms/{id}/messages |
dms |
| Integrations | /api/hooks/mattermost/{channel} |
integrations |
| Operations | /healthz, /readyz, opt-in /metrics |
deployment |
The standalone browser embeds live at
/embed/thread/{workspace_route_id}/{message_route_id} and
/embed/channel/{workspace_route_id}/{channel_route_id}. They resolve public
route IDs through the normal route API and use the same authenticated channel,
message, thread, and realtime endpoints listed above.
- All payloads are JSON unless explicitly multipart (uploads) or form-encoded (slash commands).
- Mutating endpoints return both the affected resource and the durable event
emitted (
{message, event}), so clients can reconcile optimistically. - Pagination on listings uses cursor-style sequence numbers (
after_seqfor channel/DM messages,after_cursorfor events) or opaque cursors where the ordering is not sequence-based (cursorfor workspace members). - Errors come back as
{ "error": "<message>" }with an HTTP status code. - Store-level moderation restrictions surface as
403; exhausted guest post budgets surface as429.
TypeScript consumers should use @clickclack/sdk-ts. It depends on neither
Svelte nor any HTTP framework. See ../sdk.md.