Call lifecycle
Depending on your use-case you might want to track special events related to a call, for example the start or end of a call. This guide will list the most notable events related to call lifecycle, and the order in which they sent.
For all call events please refer to the Events reference.
For time-sensitive events you can also set up push notifications on the call type level.
Creating a call
When a call is created a call.created
event is sent to all call members and to the user who created the call.
Calls can be created ahead of time (for example meetings/livestreams in the future). Unless a call is created in backstage mode (more on that below), all users that have join-call
capability can join the call.
Please note that the Stream API has an upsert behavior, so if you create a call with an ID that already exists, no new call will be created (instead it will be updated), and no call.created
event will be sent.
Ring and notify
You might want to notify users about important calls:
- Ring calls mimic traditional phone calls - we have a separate Ring call guide detailing all events (such as
call.ring
) related to ringing. - If you don’t want traditional phone calls, but want to notify members at a given time you can use the
notify
flag. Setting this flag will sendcall.notification
event to all call members. You can also send push notifications on this event, more information in the call type settings guide. You can send multiplecall.notification
events during a call’s lifecycle.
Call sessions
Starting a session
A call session starts when the first participant joins the call. A call.session_started
event is sent to all users watching the call.
You can send push notifications when a session has been started, more information in the call type settings guide
call.session_started
event reference
Participants
As participants join and leave the call session call.session_participant_joined
and call.session_participant_left
events are sent to all users watching the call.
call.session_participant_joined
event reference, call.session_participant_left
event reference
Ending a session
A call session ends when the last participant leaves the call and inactivity_timeout_seconds
elapsed (defaults to 30s). You can set a custom value for inactivity_timeout_seconds
, more information can be found here.
Ending or deleting a call will also end the session.
call.session_ended
event reference
Multiple call sessions
At a given time only one session can be active for a call. But call IDs can be reused (for example, a recurring meeting), so a call can have multiple sessions.
Backstage mode
If a call type has backstage mode enabled (for example livestream
), the call will be created in backstage mode, and only users with the join-backstage
capability can join the call. For more information on backstage, see the backstage guide.
Backstage mode is mainly used in livestream use-cases where hosts might want to gather before/after a stream.
A call can enter and leave backstage mode multiple times.
Enter backstage mode
When a call enters backstage mode the call.updated
event is sent to all users watching the call. You can check the event.call.backstage
field to know if the call is in backstage mode.
When a call type has backstage mode enabled all calls are created in backstage mode. This means that when call.created
is sent, the call is already in backstage mode (call.updated
is not sent in this case).
call.updated
event reference, call.created
event reference
Leave backstage mode (go live)
When a call goes live the call.live_started
event is sent to all users watching the call.
You can send push notifications when a call goes live, more information in the call type settings guide.
call.live_started
event reference
Ending calls
Calls can be ended by using the end call API endpoint. This operation signals to users that a call isn’t supposed to be joined anymore.
If there is an active session when the call is ended, the session will be terminated, and users will be kicked out of the call (call.session_ended
event sent immediately).
After the session is terminated, the call.ended
event is sent to all call members.
To join an ended call users need the join-ended-call
permission.
SDKs won’t end calls by default.
Deleting calls
When a call is deleted it can no longer be joined, it’s also not returned by the Stream API. For more information checkout the GDPR guide.
The call will be ended and then call.deleted
event will be sent to all users watching the call.
Examples
Below you will find examples for some common call lifecycle events.
Please note that the examples doesn’t show all Stream events, just the ones relevant for call lifecycle. The full list can be found in the Events reference.
Livestream
Example: Sara end Ben host a livestream
- Sara creates the call:
call.created
event - call is in backstage mode, only hosts can join - Sara joins the call:
call.session_started
andcall.session_participant_joined
- Ben also joins:
call.session_participant_joined
- Hosts are ready to start the livestream:
call.live_started
- Livestream ends, hosts return to backstage mode:
call.updated
- Ben and Sara leave the call: 2x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
Ring call
SDKs implement ringing flow in a way that while a call is in the ringing phase, there is no active session. The session starts when the first callee accepts the call.
All accept
Example: Sara calls Ben and Jane. Both Ben and Jane accept the call.
- Sara rings Ben and Jane (with
ring: true
):call.created
andcall.ring
events from Sara to all call members - ringing flow starts - Ben accepts the call:
call.accepted
event from Ben - Ben joins the call:
call.session_started
andcall.session_participant_joined
events - As soon as Ben accepts the call Sara also joins:
call.session_participant_joined
- Jane also accepts, and joins:
call.accepted
andcall.session_participant_joined
- Jane leaves the call:
call.participant_left
- Ben and Sara also leave: 2x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
Someone rejects
Example: Sara calls Ben and Jane. Ben accepts the call, Jane rejects.
- Sara rings Ben and Jane (with
ring: true
):call.created
andcall.ring
events from Sara to all call members - ringing flow starts - Ben accepts the call:
call.accepted
event from Ben - Ben joins the call:
call.session_started
andcall.session_participant_joined
- As soon as Ben accepts the call Sara also joins:
call.session_participant_joined
- Jane declines the call:
call.rejected
event withreason: "decline"
from Jane - Ben and Sara leave the call: 2x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
All reject
Example: Sara calls Ben and Jane. Both Jane and Ben reject the call.
- Sara rings Ben and Jane (with
ring: true
):call.created
andcall.ring
events from Sara to all call members - ringing flow starts - Ben declines the call:
call.rejected
event withreason: "decline"
from Ben - Jane is online, but doesn’t interact with the incoming call screen:
call.rejected
event withreason: "timeout"
from Jane afterincoming_call_timeout_ms
elapsed call.missed
is sent to Jane- Since both Ben and Jane rejected the call Sara will reject as well (this is sent from SDKs):
call.rejected
event withreason: "cancel"
from Sara
Caller cancels
Example: Sara calls Ben and Jane, but Sara cancels before anyone answers.
- Sara rings Ben and Jane (with
ring: true
):call.created
andcall.ring
events from Sara to all call members - ringing flow starts - Sara changes her mind, and cancels:
call.rejected
event withreason: "cancel"
from Sara
No one answers the call
Example: Sara calls Ben and Jane, but no one answers.
- Sara rings Ben and Jane (with
ring: true
):call.created
andcall.ring
events from Sara to all call members - ringing flow starts - No one accepts or rejects the call in
auto_cancel_timeout_ms
time (this can happen if users are offline, and away from their devices):call.rejected
event withreason: "timeout"
from Sara call.missed
events are sent to both Ben and Jane
Meeting with notification
Sara creates a meeting with Ben and Jane, and notifies them.
- Sara creates a meeting with Ben and Jane (with
notify: true
):call.created
andcall.notify
events - Sara joins the meeting when it’s created:
call.session_started
andcall.session_participant_joined
- Ben joins as well:
call.session_participant_joined
- Then Jane joins:
call.session_participant_joined
- The meeting ends, all participants leave the call: 3x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
Recurring meeting
Sara has a weekly meeting with Ben and Jane
- Sara creates a meeting with Ben and Jane:
call.created
event - Ben joins the meeting:
call.session_started
andcall.session_participant_joined
- Sara joins as well:
call.session_participant_joined
- Then Jane joins:
call.session_participant_joined
- The meeting ends, all participants leave the call: 3x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
Next week:
- Jane joins the meeting:
call.session_started
andcall.session_participant_joined
- Sara joins as well:
call.session_participant_joined
- Then Ben joins:
call.session_participant_joined
- The meeting ends, all participants leave the call: 3x
call.participant_left
call.session_ended
wheninactivity_timeout_seconds
elapsed since last participant left the call
Ending a call
You might have noticed that no examples contained a call.ended
event so far. That’s because by default calls are not ended, only when the end call endpoint is explicitly called. Let’s see an example for this:
- Sara creates a meeting with Ben and Jane:
call.created
event - Sara joins the meeting when it’s created:
call.session_started
andcall.session_participant_joined
- Ben joins as well:
call.session_participant_joined
- Then Jane joins:
call.session_participant_joined
- Sara ends the call:
call.session_ended
andcall.ended
events are sent