# Overview

Non-ringing push notifications let Stream notify a user about a call-related events. They are regular push notifications (FCM/APN) — your app receives the payload, displays a banner, and handle notification interaction. Unlike ringing (which the SDK handles end-to-end), **non-ringing notifications are not managed by the SDK**. Stream sends push notifications directly to the device; the rest is your app's responsibility.

## Notification types

Stream sends push notifications for the following call events. Each event can be enabled, disabled, or customized (title/body templates) in the [call type settings](/video/docs/api/ring-calls/#push-notifications/) or in corresponding section on the dashboard.

| Event                  | When it's sent                                                                                                                                                                                          |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `call.ring`            | Dispatched to call members when someone starts a call with the `ring` flag set to `true` — the start of the ringing flow. Comes as a regular notification on Android. On iOS it is sent as a VoIP push. |
| `call.notification`    | A call was created and the user should be notified without ringing (e.g. group calls, generic call notifications).                                                                                      |
| `call.missed`          | A ringing call was not answered (neither accepted nor rejected) within the configured timeout.                                                                                                          |
| `call.live_started`    | A backstage call went live (e.g. a livestream the user follows started).                                                                                                                                |
| `call.session_started` | A call session started — i.e. the first participant joined an active call.                                                                                                                              |

<admonition type="info">

`call.ring` is handled automatically by the SDK as part of the [ringing setup](/video/docs/react-native/incoming-calls/ringing/) — it powers the CallKit (iOS) and Telecom (Android) ringing UI. You don't need to handle it yourself. The remaining four events are non-ringing and can be managed inside your app depending on exact use cases.

</admonition>

All five arrive via the same transport — Firebase Cloud Messaging on Android and APNs on iOS — and carry a `sender: "stream.video"` marker in the payload so you can distinguish them from app's other notifications.

## High-level flow

Non-ringing notifications are end-to-end your app's responsibility. The typical flow is:

1. **Obtain the device push token** on the client — the FCM registration token on Android, the APNs device token on iOS.
2. **Register the token with Stream** via `client.addDevice(token, provider, providerName)`. The provider name must match a push provider configured on the [Stream Dashboard](https://dashboard.getstream.io/).
3. **Handle the incoming push** when it arrives. Parse the Stream payload, filter for non-ringing events, and display a local notification with the content you want users to see.
4. **Handle background / killed state.** On Android, Stream sends data-only FCM messages, so your app must render the notification itself — typically from a background message handler. On iOS, Stream sends standard APNs alert pushes with `aps.alert` populated; iOS renders the banner natively, so no extra work is needed on the iOS side to display it.
5. **Handle notification taps** to navigate the user to the relevant screen (e.g. the call screen identified by `call_cid`).
6. **Unregister on logout** via `client.removeDevice(token)` so Stream stops sending pushes to that device.

<admonition type="note">

To receive non-ringing push notifications, your app needs to register a device push token with Stream via `client.addDevice` — the FCM registration token on Android and the APNs device token on iOS. Registration is idempotent, so it's safe to call regardless of whether the [ringing setup](/video/docs/react-native/incoming-calls/ringing/) is also enabled.

Note that the iOS VoIP token registered automatically as part of the ringing flow doesn't apply here — VoIP tokens are PushKit-only, so a separate APNs device token must be registered for non-ringing notifications.

</admonition>

## Payload shape

Stream's push notification payload contains the following fields in `data` (Android) or nested under `stream` (iOS). On iOS, the payload also carries a standard `aps` block with `alert.title` / `alert.body` populated from the call type's push template — that's what iOS renders as the banner natively, with no app code required.

```json title="iOS APNs payload"
{
  "aps": {
    "alert": {
      "title": "Missed call",
      "body": "You missed a call from John Doe"
    },
    "category": "stream.video",
    "mutable-content": 1,
    "sound": "default",
    "thread-id": "video-default:call_id_123"
  },
  "stream": {
    "sender": "stream.video",
    "type": "call.missed",
    "version": "v2",
    "call_cid": "default:call_id_123",
    "call_display_name": "",
    "created_by_id": "john_doe",
    "created_by_display_name": "John Doe",
    "receiver_id": "artem",
    "title": "Missed call",
    "body": "You missed a call from John Doe"
  }
}
```

```json title="Android FCM payload (data-only)"
{
  "data": {
    "sender": "stream.video",
    "type": "call.missed",
    "version": "v2",
    "call_cid": "default:call_id_123",
    "call_display_name": "",
    "created_by_id": "john_doe",
    "created_by_display_name": "John Doe",
    "receiver_id": "artem",
    "title": "Missed call",
    "body": "You missed a call from John Doe"
  }
}
```

| Field                     | Description                                                                                                                                                                        |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sender`                  | Always `"stream.video"` — use this to identify Stream pushes and filter out unrelated notifications from your app.                                                                 |
| `type`                    | The event name — one of `call.ring`, `call.notification`, `call.missed`, `call.live_started`, `call.session_started` (see the table above).                                        |
| `version`                 | The payload schema version. Currently `v2`. Useful for forward compatibility if Stream adds new fields in future versions.                                                         |
| `call_cid`                | The call identifier in `<type>:<id>` format (e.g. `default:call_id_123`). Use this to navigate to the call on tap or to fetch call details.                                        |
| `call_display_name`       | The call's display name, if one was set when the call was created. Empty string when no display name was provided.                                                                 |
| `created_by_id`           | ID of the user that created the call.                                                                                                                                              |
| `created_by_display_name` | Display name of the user that created the call. Empty string when the user has no display name.                                                                                    |
| `receiver_id`             | ID of the user the notification is addressed to — i.e. the currently signed-in user on the device receiving the push.                                                              |
| `title`                   | Pre-rendered notification title from the call type's push template (placeholders like `{{ user.display_name }}` already substituted). May be empty when no template is configured. |
| `body`                    | Pre-rendered notification body from the call type's push template, with placeholders substituted. May be empty when no template is configured.                                     |


---

This page was last updated at 2026-05-25T15:27:32.637Z.

For the most recent version of this documentation, visit [https://getstream.io/video/docs/react-native/incoming-calls/non-ringing-notifications-setup/overview/](https://getstream.io/video/docs/react-native/incoming-calls/non-ringing-notifications-setup/overview/).