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
notifyflag. Setting this flag will sendcall.notificationevent 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.notificationevents 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.createdevent - call is in backstage mode, only hosts can join - Sara joins the call:
call.session_startedandcall.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_endedwheninactivity_timeout_secondselapsed 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.createdandcall.ringevents from Sara to all call members - ringing flow starts - Ben accepts the call:
call.acceptedevent from Ben - Ben joins the call:
call.session_startedandcall.session_participant_joinedevents - As soon as Ben accepts the call Sara also joins:
call.session_participant_joined - Jane also accepts, and joins:
call.acceptedandcall.session_participant_joined - Jane leaves the call:
call.participant_left - Ben and Sara also leave: 2x
call.participant_left call.session_endedwheninactivity_timeout_secondselapsed 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.createdandcall.ringevents from Sara to all call members - ringing flow starts - Ben accepts the call:
call.acceptedevent from Ben - Ben joins the call:
call.session_startedandcall.session_participant_joined - As soon as Ben accepts the call Sara also joins:
call.session_participant_joined - Jane declines the call:
call.rejectedevent withreason: "decline"from Jane - Ben and Sara leave the call: 2x
call.participant_left call.session_endedwheninactivity_timeout_secondselapsed 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.createdandcall.ringevents from Sara to all call members - ringing flow starts - Ben declines the call:
call.rejectedevent withreason: "decline"from Ben - Jane is online, but doesn’t interact with the incoming call screen:
call.rejectedevent withreason: "timeout"from Jane afterincoming_call_timeout_mselapsed call.missedis sent to Jane- Since both Ben and Jane rejected the call Sara will reject as well (this is sent from SDKs):
call.rejectedevent 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.createdandcall.ringevents from Sara to all call members - ringing flow starts - Sara changes her mind, and cancels:
call.rejectedevent 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.createdandcall.ringevents from Sara to all call members - ringing flow starts - No one accepts or rejects the call in
auto_cancel_timeout_mstime (this can happen if users are offline, and away from their devices):call.rejectedevent withreason: "timeout"from Sara call.missedevents 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.createdandcall.notifyevents - Sara joins the meeting when it’s created:
call.session_startedandcall.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_endedwheninactivity_timeout_secondselapsed 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.createdevent - Ben joins the meeting:
call.session_startedandcall.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_endedwheninactivity_timeout_secondselapsed since last participant left the call
Next week:
- Jane joins the meeting:
call.session_startedandcall.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_endedwheninactivity_timeout_secondselapsed 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.createdevent - Sara joins the meeting when it’s created:
call.session_startedandcall.session_participant_joined - Ben joins as well:
call.session_participant_joined - Then Jane joins:
call.session_participant_joined - Sara ends the call:
call.session_endedandcall.endedevents are sent