Call Types

When you create a call like this:

var callType = StreamCallType.Default;
var callId = "my-call-id";

var streamCall = await _client.GetOrCreateCallAsync(callType, callId);

or when you join a call like this:

var callType = StreamCallType.Default;
var callId = "my-call-id";

var streamCall = await _client.JoinCallAsync(callType, callId, create: true, ring: false, notify: false);

Apart from setting the callId you also pick the StreamCallType.

There are 6 built-in call types, and you can also create your own.

The Video SDK provides pre-defined call types with different default permissions and feature configurations. You can extend these or create custom types via the dashboard.

Best Practices

  • Use the development call type only for testing, never in production
  • Configure call types in the dashboard before deploying to production
  • Set up proper user roles to simplify permission management
  • Use backstage mode for scheduled calls or livestreams that need preparation time
  • Review default capabilities and customize them based on your security requirements

Key Concepts

  • Call Type - Pre-defined configurations with associated user roles and capabilities. Six default types are available, or create custom types via the dashboard.
  • User Role - Defines what actions a user can perform. Users can have multiple roles. Use existing roles or define custom ones via the dashboard.
  • Call Capabilities - Specific actions a participant can perform (such as send-video or end-call). Associated with user roles and customizable via the dashboard.

Call Types

Six pre-defined call types are available:

  • development - All permissions enabled; use only for testing
  • default - 1-1 or group video calls with sensible defaults
  • audio_call - 1:1 or group voice calls with phone-call semantics: the call rings, is audio-only, and is over once it ends
  • agent - Conversations that start between a user and an AI agent, voice first and private by default
  • livestream - All authenticated users can access calls; ideal for one-to-many broadcasting
  • audio_room - Pre-configured for audio-only experiences with permission request workflows (like Clubhouse or Twitter Spaces)

Each call type includes specific settings. The backstage concept allows calls to be created but not directly joined until GoLiveAsync() is called, useful for scheduled calls.

Development

The development call type has all permissions enabled for testing purposes. Do not use in production since all participants can perform any action (blocking, muting, etc).

Backstage is disabled, so calls start immediately without requiring GoLiveAsync().

Default

The default call type supports 1-1 calls, group calls, and meetings. Video and audio are enabled, backstage is disabled, and admins/hosts have elevated permissions.

Info:

The default type can be used in apps that use regular video calling. To learn more try our tutorial on building a video calling app.

Audio Call

The audio_call call type is the preset for voice calls between people, with phone-call semantics: the caller rings one or more people, the call is audio-only, and it is over once it ends. Like default, it is available on every app without any setup.

Its defaults follow from that use case:

  • A call that rings. The ring timeouts are 30 s for the incoming-call screen and for the caller's auto-cancel, and 33 s for the server's missed-call deadline, so the server settles a missed call just after the callee's screen has gone. The default type uses 15 s, 15 s and 18 s.
  • Held to the ear. Users join with the microphone on, the earpiece as the default device and the speaker off. Opus DTX and redundant coding are on, so silence costs no bandwidth and speech survives packet loss. Noise cancellation is available for clients to turn on.
  • Audio only. Video, screen sharing, backstage, broadcasting (HLS and RTMP), frame recording and access requests are disabled. Recording, transcription and closed captions are available but never start on their own, and the composite recording is audio-only.
  • No "call started" pushes. Ring, notification and missed-call pushes are sent as usual. session_started and call_live_started pushes are disabled, since the ring already woke the callee.
  • One call per conversation. lifecycle.mode is single_use: the call ends when the caller cancels the ring (which the SDKs also do when nobody accepts in time), or when the server's missed-call timeout passes with nobody having accepted or joined, for example because the caller's app has gone. An ended call cannot be joined or re-created with get-or-create, whatever the permissions say. See call lifecycle.

One-to-one or group

audio_call sets no participant limit. The ring decides the shape of the call:

  • One callee is the phone call the type is named after.
  • Several callees. Create the call with more than one member and ring: true. Every callee gets the ring push, and the call runs as soon as one of them accepts. A callee who rejects or lets it ring drops out of the ring; the call keeps going for the others.
  • Adding people later works on the running call: add them as call members and ring them with the ring endpoint (members_ids). They join the same call.

Only the end is terminal: the caller's cancel, a ring that times out on the server with nobody answering, an explicit end-call, deleting the call, a max_duration_seconds limit or a moderation action ends the call, and an ended single_use call refuses every join. Everyone leaving does not end it. max_participants is not a way to enforce one-to-one: the call owner is exempt from it by default (max_participants_exclude_owner), and so are roles listed in max_participants_exclude_roles.

Use audio_call when a person starts a call to other people, with an AI agent as at most one more participant. Use agent when the conversation starts with an AI agent.

If your app already has an audio_call call type

If you created a custom call type named audio_call before it became built-in, its stored settings keep applying, settings it does not store now come from the audio_call defaults instead of the default ones, and its lifecycle stays reusable. To adopt phone-call semantics, set lifecycle.mode to single_use on it with update call type. Switching the type to single_use also switches its existing calls, ended ones included, unless a call set its own mode when it was created, so if your app reuses call IDs on that type, get-or-create fails for an ID whose call has ended. Permissions do not change: audio_call has no grants of its own, so it uses the built-in default grants, not changes made to your app's default type.

Agent

The agent call type is built for conversations that start between a user and an AI agent, such as a voice or vision agent built with Vision Agents. Like default, it is available on every app without any setup. It pairs with the agent channel type, which can hold the text side of the same conversation.

Its defaults follow from that use case:

  • Voice first. Users join with the microphone on and audio on the speaker, since assistant-style apps are used hands-free. The camera is off by default. Video and screen sharing stay enabled, so a vision agent can see the camera or a shared screen once the user turns them on.
  • Audio the agent can work with. Opus DTX is off, because the agent's voice activity and turn detection need a continuous audio stream. Noise cancellation is disabled, so the agent receives the user's unprocessed voice.
  • Private. Backstage, broadcasting (HLS and RTMP) and access requests are disabled. Recording, frame recording, transcription and closed captions are available but never start on their own, so nothing is billed unless you start it.
  • No ringing. The user starts the conversation and your backend sends the agent in, so the ringing timeouts are 0. Ring, notification and missed-call pushes are still sent when you ask for them (ring: true or notify: true), so an agent can still call a user. session_started and call_live_started pushes are disabled: the agent usually joins first, and the user would otherwise get a "call started" push for their own conversation.
  • One conversation, one call. lifecycle.mode is single_use, as on audio_call. The agent SDKs create a fresh call for every conversation and nothing sends an agent back into an ended call, so an ended call cannot be joined or re-created with get-or-create, whatever the permissions say: start a new call instead. See call lifecycle.

Permissions

Joining is open, as on default: any user who knows the call ID can join and send audio and video without being a call member. Guests can join and talk, but cannot create calls, share their screen or send reactions. Control over the conversation is narrower than on default:

Action user call_member admin
Join, send audio and video, share screen, send closed captions Any call Any call Any call
Create calls Yes Yes Yes
End the call, join an ended call Calls they created Yes Yes
Start and stop recording, frame recording, transcription and closed captions; list recordings and transcriptions Calls they created Yes Yes
Update the call or its settings, mute, block, kick, pin, remove or update members Calls they created Calls they created Yes
Start and stop broadcasting No No Yes
Delete the call, its recordings or transcriptions; read call stats No No Yes

agent is single_use, so an ended call refuses every join whatever the grants say. The join-ended-call permission in the table only matters for an app that sets the type back to reusable, or for a call created with a reusable override.

Two setups cover most apps:

  • The agent creates the call. This is how Vision Agents sets up a conversation: the agent's user creates and owns the call, and the user joins with their own token without being a member. The agent controls recording and transcription. The user can talk, but cannot record the conversation or end it for everyone.
  • Your backend creates the call with both as members. Create the call with the user and the agent's user as call members. Both can then record, transcribe and end the call. Use this setup when your app shows record or end-call buttons to the user.

One human and one agent, or more

The type is chosen by how the conversation starts, not by a participant cap: agent sets no max_participants, joining is open, and nothing refuses a third participant. An escalation stays in the same call:

  • A human supervisor is pulled in. Your backend, or the agent through a server SDK, adds the supervisor as a call member and rings them with the ring endpoint (members_ids) on the running call. They join as a call member, so they can record, transcribe or end the conversation. The type leaves the ring timeouts at 0, so the server's missed-call deadline falls back to its default of 30 s; set ring timeouts in the call's settings_override (with update call on a running call) if the clients should time the ring themselves. The server's deadline then becomes incoming_call_timeout_ms plus 3 s.
  • A second agent joins. Send it into the same call ID, like the first one. There is no hand-over call.
  • The agent calls a person. Create the call with the person as a member and ring: true. Under single_use the call ends when the ring times out unanswered (30 s by default, since the type sets no ring timeouts) or when the caller cancels it from a client, so a retry is a new call.

Use agent when the conversation starts with an AI agent, and audio_call when a person starts a call to other people, with an agent as at most one more participant.

If your app already has an agent call type

If you created a custom call type named agent before it became built-in, its stored settings keep applying, and settings it does not store now come from the agent defaults instead of the default ones. Its permissions can change too: grants stored on that type are kept as changes to the type's built-in grants, which are now the agent grants above instead of the default ones, and a role with nothing stored uses the agent grants as they are. Check the type with get call type and set the grants explicitly for every role that should keep its previous behavior. Its lifecycle stays reusable; set lifecycle.mode to single_use on it to match the built-in. Switching the type to single_use also switches its existing calls, ended ones included, unless a call set its own mode when it was created, so if your app reuses call IDs on that type, get-or-create fails for an ID whose call has ended.

Livestream

The livestream call type is configured for live streaming apps. All authenticated users can access calls, and backstage is enabled by default.

Info:

There is no Unity livestreaming tutorial yet. Start from the Quickstart, then use GoLiveAsync() to leave backstage and StartHLS() to broadcast.

Audio Room

The audio_room call type suits apps like Clubhouse or Twitter Spaces. It includes a pre-configured workflow for requesting speaking permissions. Backstage is enabled by default; call GoLiveAsync() to make the call active for all participants.

Info:

See the Audio Room tutorial for implementation details.


Call type settings

Each call type has configurable settings. See the defaults table for a comparison of settings across call types.

Audio

Setting Name Type Description
access_request_enabled Boolean When true users that do not have permission to this feature can request access for it
opus_dtx_enabled Boolean When true OPUS DTX is enabled
redundant_coding_enabled Boolean When true redundant audio transmission is enabled
mic_default_on Boolean When true the user will join with the microphone enabled by default
speaker_default_on Boolean When true the user will join with the audio turned on by default
default_device String speaker or earpiece The default audio device to use

Backstage

Setting Name Type Description
enabled Boolean When backstage is enabled, calls will be in backstage mode when created and can be joined by users only after goLive is called

Video

Setting Name Type Description
enabled Boolean Defines whether video is enabled for the call
access_request_enabled Boolean When true users that do not have permission to this feature can request access for it
camera_default_on Boolean When true, the camera will be turned on when joining the call
camera_facing String front, back or external When applicable, the camera that should be used by default
target_resolution Target Resolution Object The ideal resolution that video publishers should send

The target resolution is an advanced setting. Modifying defaults can degrade performance. Structure:

Setting Name Type Description
width Number The width in pixels
height Number The height in pixels
bitrate Number The bitrate

Screensharing

Setting Name Type Description
enabled Boolean Defines whether screensharing is enabled
access_request_enabled Boolean When true users that do not have permission to this feature can request access for it

Recording

Setting Name Type Description
mode String available, disabled or auto-on available → recording can be requested
disabled → recording is disabled
auto-on → recording starts and stops automatically when one or multiple users join the call
quality String audio-only, 360p, 480p, 720p, 1080p, 1440p Defines the resolution of the recording
audio_only boolean If true the recordings will only contain audio
layout object, for more information see the API docs Configuration options for the recording application

Broadcasting

Setting Name Type Description
enabled Boolean Defines whether broadcasting is enabled
hls HLS Settings (object) Settings for HLS broadcasting

HLS Settings

Setting Name Type Description
enabled Boolean Defines whether HLS is enabled or not
auto_on Boolean When true HLS streaming will start as soon as users join the call
quality_tracks String audio-only, 360p, 480p, 720p, 1080p, 1440p The tracks to publish for the HLS stream (up to three tracks)

Geofencing

Setting Name Type Description
names List of one or more of these strings european_union, iran_north_korea_syria_exclusion, china_exclusion, russia_exclusion, belarus_exclusion, india, united_states, canada The list of geofences that are used for the calls of these type

See the API docs for details.

Transcription

Setting Name Type Description
mode String available, disabled or auto-on Not implemented yet
closed_caption_mode String Not implemented yet

Ringing

Setting Name Type Description
incoming_call_timeout_ms Number Defines how long the SDK should display the incoming call screen before discarding the call (in ms)
auto_cancel_timeout_ms Number Defines how long the caller should wait for others to accept the call before canceling (in ms)
missed_call_timeout_ms Number How long the server waits for an accept before it settles the ring as missed for a member who did not answer (in ms). Values below 5000 mean the default of 30000. A call whose settings_override sets incoming_call_timeout_ms uses that value plus 3000 instead

Lifecycle

Setting Name Type Description
mode String reusable or single_use reusable (the default) keeps a call open after its ring, so it can be rung again, and lets users with the join-ended-call permission join it after it has ended. single_use gives phone-call semantics: the call ends when the caller cancels the ring or the ring times out unanswered, and the ended call can no longer be joined or returned by get-or-create, whatever the permissions; create a new call instead. The built-in audio_call and agent types use single_use. See call lifecycle for the full behavior and how the mode resolves.

Push Notifications Settings

Setting Name Type Description
enabled Boolean
call_live_started Event Notification Settings Object The notification settings used for call_live_started events
session_started Event Notification Settings Object The notification settings used for session_started events
call_notification Event Notification Settings Object The notification settings used for call_notification events
call_ring Event Notification Settings Object The notification settings used for call_ring events

Event notification settings object structure:

Setting Name Type Description
enabled Boolean Whether this object is enabled
apns APNS Settings Object The settings for APN notifications

APNS Settings Object

Customize remote notifications by implementing a Notification Service Extension. For simple customizations, modify the title and body fields at the call type level. Both fields are handlebars templates with call and user objects in scope.

Setting Name Type Description
title Template The string template for the title field of the notification
body Template The string template for the body field of the notification

Defaults for call type settings

development default audio-call agent livestream audio-room
Audio
access_request_enabled ✅ ✅ ❌ ❌ ❌ ✅
opus_dtx_enabled ✅ ✅ ✅ ❌ ✅ ✅
redundant_coding_enabled ✅ ✅ ✅ ✅ ✅ ✅
mic_default_on ✅ ✅ ✅ ✅ ❌ ❌
speaker_default_on ✅ ✅ ❌ ✅ ✅ ✅
default_device earpiece earpiece earpiece speaker speaker speaker
Backstage
enabled ❌ ❌ ❌ ❌ ✅ ✅
Video
enabled ✅ ✅ ❌ ✅ ✅ ❌
access_request_enabled ✅ ✅ ❌ ❌ ❌ ❌
target_resolution Width: 1280
Height: 720
Bitrate 1500000
Width: 1280
Height: 720
Bitrate 1500000
N/A Width: 1280
Height: 720
Bitrate 1500000
Width: 1920
Height: 1080
Bitrate 3000000
N/A
camera_default_on ✅ ✅ ❌ ❌ ✅ ❌
camera_facing front front front front front front
Screensharing
enabled ✅ ✅ ❌ ✅ ✅ ✅
access_request_enabled ✅ ✅ ❌ ❌ ❌ ✅
Recording
mode available available available available available available
quality 720p 720p 720p 720p 720p N/A
audio_only ❌ ❌ ✅ ❌ ❌ ✅
Broadcasting
enabled ✅ ✅ ❌ ❌ ✅ ✅
hls.auto_on ❌ ❌ ❌ ❌ ❌ ❌
hls.enabled available available ❌ ❌ available available
hls.quality_tracks [720p] [720p] [720p] [720p] [720p] [720p]
Geofencing
names [] [] [] [] [] []
Transcriptions
mode available available available available available available
Ringing
incoming_call_timeout_ms 0 15000 30000 0 0 0
auto_cancel_timeout_ms 15000 15000 30000 0 0 0
missed_call_timeout_ms 0 18000 33000 0 0 0
Lifecycle
mode reusable reusable single_use single_use reusable reusable

User roles

Five pre-defined user roles are available:

  • user - Standard participant
  • moderator - Can moderate calls
  • host - Call host with elevated permissions
  • admin - Full administrative access
  • call-member - Basic call membership

Each role has associated capabilities. Access default roles and capabilities in the Stream Dashboard. A well-defined role setup simplifies permission management.

Call Capabilities

A capability defines actions a user can perform on a call. Each user has capabilities attached based on their role. Modify default capabilities in the dashboard or change them dynamically at runtime.

Users with permission to assign capabilities can grant them to other users, enabling flexible permission management.

Info:

If you want to learn more about doing this, head over to the Permissions and Capabilities chapter.

Default call capabilities

When fetching a call from the API, the response includes the user's allowed actions:

  • join-call
  • read-call
  • create-call
  • join-ended-call
  • join-backstage
  • update-call
  • update-call-settings
  • screenshare
  • send-video
  • send-audio
  • start-record-call
  • stop-record-call
  • start-broadcast-call
  • stop-broadcast-call
  • end-call
  • mute-users
  • update-call-permissions
  • block-users
  • create-reaction
  • pin-for-everyone
  • remove-call-member
  • start-transcription-call
  • stop-transcription-call