guides

Join a private intercom

Intercom audio is private crew communication. Joining does not add a program source or broadcast a microphone, camera, or screen. Availability depends on the studio's intercom capability. A successful control request confirms membership; it does not prove that another participant can hear audio.

Use intercom:read to read GET /v1/studios/{studioId}/intercom/rooms and receive room status over the studio event stream. Use intercom:join for membership operations. Microphone enablement additionally requires intercom:publish and studio edit permission; listening requires studio view permission. These scopes are explicit and are not added to existing API keys automatically.

Join listening

Send POST /v1/studios/{studioId}/intercom/memberships:

{"channel":"crew","idempotencyKey":"client-generated-unique-attempt-key"}

Retain the key for retries of this same join attempt. A new deliberate join after leaving uses a new key. Retrying an old or retired attempt cannot replace a newer membership. The response contains an opaque membershipId, a room snapshot, media endpoints, a private token, and separate membership and credential expiry times. Treat the token and TURN credentials as secrets; do not log them or send them through the event stream.

Subscribe to the other publishing participants' audioPath values using the returned media base and credentials. Exclude your own publish path. A microphone grant does not mean the publisher has started sending media: watch its reported microphoneState, and handle a bounded initial stream-readiness delay. Keep playback blocked/pending/error visible; browsers may require an explicit user gesture to enable audio.

Request a microphone explicitly

Only after an explicit local user gesture, send POST /v1/studios/{studioId}/intercom/memberships/{membershipId}/microphone with:

{"publish":true}

The client must independently request microphone permission and publish only that audio track using the returned grant. Never capture a device merely because a roster or refreshed grant says canPublish:true. Keep the microphone muted until the publisher connects and the operator explicitly chooses to talk.

Send {"publish":false} to withdraw microphone permission while retaining listening. Stop the client's owned publisher and microphone tracks immediately. This control operation cannot instantly revoke a previously issued media token or an already accepted media session; do not rely on it as remote media teardown.

Refresh, leave, and report local state

Refresh the current membership before either expiry with bodyless POST /v1/studios/{studioId}/intercom/memberships/{membershipId}/refresh. Refresh never upgrades a listener to a publisher. A key without intercom:publish cannot retrieve a publishing credential after another client has upgraded that membership; request a deliberate downgrade or use an appropriately authorized key. Stop owned media when access expires or refresh fails. An expired membership requires a new deliberate join.

Use PATCH /v1/studios/{studioId}/intercom/memberships/{membershipId} for partial listen/talk state and bounded local transport reports:

{"listenState":"connected","microphoneState":"idle","mediaErrorCode":""}

Media states are idle, connecting, connected, or failed. Safe error codes are listed in the API reference; never submit raw device errors, tokens, SDP, or private URLs. The server stamps mediaObservedAt. These are client reports, not independent server measurements of audible audio. A failed talk update must leave the local microphone muted.

Leave with DELETE /v1/studios/{studioId}/intercom/memberships/{membershipId} and stop all owned tracks/readers. Delayed responses must be discarded when their studio, connection, or membership no longer matches the current client state. A stale leave must never target the client's newer membership.

Reconcile room events

GET /v1/studios/{studioId}/events carries whole-room intercom events and snapshot intercomRooms when the key has intercom:read in addition to the normal event-stream scopes. Grant tokens and TURN credentials are excluded. Replace that room's roster, including when it becomes empty. Preserve the studio/room boundary, and show reported progress and failure separately from control membership.

After a disconnect, use the fresh snapshot or the room read endpoint to recover missed state. Last-Event-ID participates in the existing stream contract; it is not a promise of durable replay of every intermediate audio status change.