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.
Recording & AI consent
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.