Reference

API reference

The complete shipped surface — 81 HTTP operations across five planes, plus two WebSocket channels documented separately. Grouped by the credential each plane takes, because that is the thing most likely to trip you up.

The machine-readable OpenAPI document is the source of truth and is kept in lockstep with the router by a parity check that fails the build — an endpoint cannot ship undocumented, and a documented endpoint cannot vanish. See WebSocket protocol for the socket frames.

Customer server API #

Credential: ak_ server key

Your backend calls these. Tenant comes from the key — a tenant_id in a body is rejected. Scope-gated.

Rooms & members

POST /v1/server/rooms Provision a room (idempotent on external_ref)
GET /v1/server/rooms/{room_id} Fetch a room
DELETE /v1/server/rooms/{room_id} Erase a room — rows and blobs
POST /v1/server/rooms/{room_id}/members Add or restore a member
DELETE /v1/server/rooms/{room_id}/members/{principal_id} Remove a member

Tokens, principals, messages

POST /v1/server/session-tokens Mint a room-scoped client token
POST /v1/server/principals Register a principal (bot/service identity)
POST /v1/server/principals/{principal_id}/erase GDPR erase a principal
POST /v1/server/rooms/{room_id}/messages Send as a principal (server-side)

Usage & webhooks

GET /v1/server/usage Metered usage for a window
POST /v1/server/webhooks Create an endpoint subscription
GET /v1/server/webhooks List endpoints
DELETE /v1/server/webhooks/{webhook_id} Delete an endpoint
GET /v1/server/webhooks/{webhook_id}/deliveries Delivery audit log
POST /v1/server/webhooks/{webhook_id}/deliveries/{delivery_id}/replay Replay a delivery

Client API #

Credential: room-scoped session token

What your app calls directly. Every path is authorised against the token’s room and principal.

Messages

POST /v1/rooms/{room_id}/messages Send
GET /v1/rooms/{room_id}/messages History (after_seq / before_seq / limit)
PATCH /v1/rooms/{room_id}/messages/{message_id} Edit (author only)
DELETE /v1/rooms/{room_id}/messages/{message_id} Soft delete
GET /v1/rooms/{room_id}/messages/search Full-text search within the room
POST /v1/rooms/{room_id}/messages/{message_id}/reactions Add a reaction
DELETE /v1/rooms/{room_id}/messages/{message_id}/reactions Remove a reaction

Receipts & presence

POST /v1/rooms/{room_id}/messages/{message_id}/delivered Delivery receipt
POST /v1/rooms/{room_id}/messages/{message_id}/read Read receipt (advances cursor)
GET /v1/rooms/{room_id}/unread Unread count and cursors
GET /v1/rooms/{room_id}/participants Room participants

Attachments

POST /v1/rooms/{room_id}/attachments/init Begin an upload
POST /v1/rooms/{room_id}/attachments/{attachment_id}/complete Finish and verify
POST /v1/rooms/{room_id}/attachments/init-multipart Begin a multipart upload
POST /v1/rooms/{room_id}/attachments/{attachment_id}/complete-multipart Finish multipart
GET /v1/rooms/{room_id}/attachments/{attachment_id}/download Presigned download

Push

POST /v1/push/subscriptions Register a Web Push subscription
DELETE /v1/push/subscriptions Unregister one
GET /v1/push/vapid-public-key VAPID public key

End-to-end encryption

POST /v1/e2ee/keys/upload Publish device + one-time keys
POST /v1/e2ee/keys/query Query devices for principals
POST /v1/e2ee/keys/claim Claim a one-time key (atomic)
POST /v1/e2ee/todevice Send a to-device message
GET /v1/e2ee/todevice Fetch queued to-device messages
POST /v1/keypackages Upload MLS key packages
GET /v1/keypackages/count Remaining key-package count
GET /v1/rooms/{room_id}/keypackages/{principal_id} Consume one key package

Directory (end-user) API #

Credential: du_ directory session — or none for OTP

The turnkey identity plane. Your client calls these directly.

Sign-in & profile

POST /v1/directory/otp/request Request a one-time code (unauthenticated)
POST /v1/directory/otp/verify Verify and receive a du_ session
GET /v1/directory/me Current user
PATCH /v1/directory/me Update display name

Contacts & conversations

POST /v1/directory/contacts/lookup Which phone numbers are registered (≤500)
POST /v1/directory/conversations/direct Open a 1:1 (idempotent)
POST /v1/directory/conversations/group Create a group
GET /v1/directory/conversations List conversations
GET /v1/directory/conversations/{room_id}/token Mint a room token
GET /v1/directory/inbox Chat list: peer, last message, unread

Devices

POST /v1/directory/devices Register a push token
GET /v1/directory/devices List devices
DELETE /v1/directory/devices Unregister a push token

Account API #

Credential: as_ account session

Self-serve control surface. Dashboard/admin credential — never ship it in a product build.

Account

POST /v1/account/signup Create an account and its tenant
POST /v1/account/login Log in
POST /v1/account/logout Invalidate the session

API keys

GET /v1/account/api-keys List keys
POST /v1/account/api-keys Create a key (secret shown once)
POST /v1/account/api-keys/{key_id}/rotate Rotate atomically
DELETE /v1/account/api-keys/{key_id} Revoke

Directory apps

POST /v1/account/directory-apps Provision an app (webhook or SMS provider)
GET /v1/account/directory-apps List apps and which push transports are configured
DELETE /v1/account/directory-apps/{app_id} Delete an app
PUT /v1/account/directory-apps/{app_id}/push Set FCM/APNs credentials (write-only)

Operator control plane #

Credential: HMAC-signed

Deployment-wide, for whoever runs the infrastructure. As a customer you should never need these.

Rooms, members, tokens

POST /internal/v1/rooms Create a room
GET /internal/v1/rooms Resolve by external_ref
PATCH /internal/v1/rooms/{room_id} Patch status / expiry
GET /internal/v1/rooms/{room_id}/status Members, presence, live call roster
POST /internal/v1/rooms/{room_id}/members Add a member
DELETE /internal/v1/rooms/{room_id}/members/{principal_id} Remove a member
POST /internal/v1/session-tokens Mint a token
GET /internal/v1/principals/{principal_id}/unread Per-room unread for a principal

Provisioning & lifecycle

POST /internal/v1/api-keys Issue a customer key
DELETE /internal/v1/api-keys/{key_id} Revoke a key
PUT /internal/v1/plans/{name} Create/update a rate + quota plan
DELETE /internal/v1/tenants/{tenant_id} Offboard a tenant (full erasure)

Operational #

Credential: none / internal

Health and telemetry. Metrics is not publicly exposed.

Health

GET /health/live Liveness
GET /health/ready Readiness (dependencies)
GET /metrics Prometheus metrics — internal only

Conventions #

  • All bodies are JSON; all timestamps are RFC 3339 UTC.
  • Errors carry code and message — see Errors & rate limits.
  • /v1 is additive-only, with a 90-day deprecation notice signalled by Deprecation and Sunset headers.
  • Writes that can be retried take an idempotency key (client_message_id for messages, external_ref for rooms).