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.

call.created event reference

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 send call.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 multiple call.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.

call.ended event reference

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.

call.deleted event reference

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

  1. Sara creates the call: call.created event - call is in backstage mode, only hosts can join
  2. Sara joins the call: call.session_started and call.session_participant_joined
  3. Ben also joins: call.session_participant_joined
  4. Hosts are ready to start the livestream: call.live_started
  5. Livestream ends, hosts return to backstage mode: call.updated
  6. Ben and Sara leave the call: 2x call.participant_left
  7. call.session_ended when inactivity_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.

  1. Sara rings Ben and Jane (with ring: true): call.created and call.ring events from Sara to all call members - ringing flow starts
  2. Ben accepts the call: call.accepted event from Ben
  3. Ben joins the call: call.session_started and call.session_participant_joined events
  4. As soon as Ben accepts the call Sara also joins: call.session_participant_joined
  5. Jane also accepts, and joins: call.accepted and call.session_participant_joined
  6. Jane leaves the call: call.participant_left
  7. Ben and Sara also leave: 2x call.participant_left
  8. call.session_ended when inactivity_timeout_seconds elapsed since last participant left the call

Someone rejects

Example: Sara calls Ben and Jane. Ben accepts the call, Jane rejects.

  1. Sara rings Ben and Jane (with ring: true): call.created and call.ring events from Sara to all call members - ringing flow starts
  2. Ben accepts the call: call.accepted event from Ben
  3. Ben joins the call: call.session_started and call.session_participant_joined
  4. As soon as Ben accepts the call Sara also joins: call.session_participant_joined
  5. Jane declines the call: call.rejected event with reason: "decline" from Jane
  6. Ben and Sara leave the call: 2x call.participant_left
  7. call.session_ended when inactivity_timeout_seconds elapsed since last participant left the call

All reject

Example: Sara calls Ben and Jane. Both Jane and Ben reject the call.

  1. Sara rings Ben and Jane (with ring: true): call.created and call.ring events from Sara to all call members - ringing flow starts
  2. Ben declines the call: call.rejected event with reason: "decline" from Ben
  3. Jane is online, but doesn’t interact with the incoming call screen: call.rejected event with reason: "timeout" from Jane after incoming_call_timeout_ms elapsed
  4. call.missed is sent to Jane
  5. Since both Ben and Jane rejected the call Sara will reject as well (this is sent from SDKs): call.rejected event with reason: "cancel" from Sara

Caller cancels

Example: Sara calls Ben and Jane, but Sara cancels before anyone answers.

  1. Sara rings Ben and Jane (with ring: true): call.created and call.ring events from Sara to all call members - ringing flow starts
  2. Sara changes her mind, and cancels: call.rejected event with reason: "cancel" from Sara

No one answers the call

Example: Sara calls Ben and Jane, but no one answers.

  1. Sara rings Ben and Jane (with ring: true): call.created and call.ring events from Sara to all call members - ringing flow starts
  2. 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 with reason: "timeout" from Sara
  3. call.missed events are sent to both Ben and Jane

Meeting with notification

Sara creates a meeting with Ben and Jane, and notifies them.

  1. Sara creates a meeting with Ben and Jane (with notify: true): call.created and call.notify events
  2. Sara joins the meeting when it’s created: call.session_started and call.session_participant_joined
  3. Ben joins as well: call.session_participant_joined
  4. Then Jane joins: call.session_participant_joined
  5. The meeting ends, all participants leave the call: 3x call.participant_left
  6. call.session_ended when inactivity_timeout_seconds elapsed since last participant left the call

Recurring meeting

Sara has a weekly meeting with Ben and Jane

  1. Sara creates a meeting with Ben and Jane: call.created event
  2. Ben joins the meeting: call.session_started and call.session_participant_joined
  3. Sara joins as well: call.session_participant_joined
  4. Then Jane joins: call.session_participant_joined
  5. The meeting ends, all participants leave the call: 3x call.participant_left
  6. call.session_ended when inactivity_timeout_seconds elapsed since last participant left the call

Next week:

  1. Jane joins the meeting: call.session_started and call.session_participant_joined
  2. Sara joins as well: call.session_participant_joined
  3. Then Ben joins: call.session_participant_joined
  4. The meeting ends, all participants leave the call: 3x call.participant_left
  5. call.session_ended when inactivity_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:

  1. Sara creates a meeting with Ben and Jane: call.created event
  2. Sara joins the meeting when it’s created: call.session_started and call.session_participant_joined
  3. Ben joins as well: call.session_participant_joined
  4. Then Jane joins: call.session_participant_joined
  5. Sara ends the call: call.session_ended and call.ended events are sent
© Getstream.io, Inc. All Rights Reserved.