Security model

What crosses the boundary, and what never does.

The identity seam

Only externalUserId + displayName cross to the platform. The platform stores no other end-user PII. externalUserId is your identifier for the user; the platform never sees your user table. Keep the mapping stable and one-directional: the platform stores the opaque id; you resolve it to a person.

Because room names are broadcast to every participant and rendered in every client, do not put personal identifiers in Room.name — use externalId/externalMetadata for correlation; those stay server-side.

Credential placement

The tenant API key and webhook secret live on your backend only; the browser only ever holds a single-participant, short-lived join token. See Authentication & credentials.

E2EE rooms are opaque server-side

The encryption key rides the URL fragment and never reaches the platform, so server-side features (recording, streaming, AI) cannot operate on encrypted rooms. See End-to-end encryption.

Join tokens travel in a query string

The join token reaches access logs and same-origin Referer headers. It is single-participant and short-lived (6h by default); treat a join URL as a secret and don't persist it.

Rooms carry their recording/AI configuration in the public room facts (GET /rooms/{id}/info and the token's metadata claim), and the hosted pre-join surfaces display a consent notice for recorded or AI-transcribed meetings. If you build your own client, render an equivalent notice.

Not covered yet

Official SDKs beyond the generated OpenAPI client, and formal deprecation windows.

On this page