Notifications

Send Notification

Changed on

Sends a notification to one user's devices (target.app_user_id, with devices: "all" or "latest") or to one device (target.device_id), across every application of the project whose notifications are enabled. Delivery is through APNs with the application's APNs key.

The response is 202 { "id", "status": "queued" } once the send is accepted. Superwall then resolves the target to its devices and delivers to each one the user allows notifications on (a background notification also reaches devices whose permission is off). Each device's outcome arrives later as a NOTIFICATION_SENT or NOTIFICATION_FAILED webhook and a notification_send / notification_fail event, all carrying this send's id. A target with no registered device is accepted and delivers nothing.

Send notification content (title, subtitle, body, badge or sound), content_available: true for a background notification, or both. A background notification has no visible content, always uses normal priority, and reaches devices whose notification permission is off. The encoded APNs payload (including data and Superwall's sw key) must be at most 4096 bytes.

idempotency_key is required: the same key within 30 days returns the original response and sends nothing; the same key with a different body answers 409 idempotency_key_in_use, as does a retry while the first request is still being processed. After a 503, retry with the same key and body: the retry sends under the same id, and a device that already received the notification may receive it again.

Answers 404 when no application of the project has notifications enabled, 409 credentials_missing when none of those applications has an APNs key (an application without one is left out of the send), and 400 for a placeholder app_user_id (null, undefined, 0, ...), reserved data keys (aps, sw, deep_link), or a payload over 4096 bytes.

Requires notifications:send scope.

post/v2/projects/{id}/notifications

Request

  • Base URL
    https://api.superwall.com
  • URL
    https://api.superwall.com/v2/projects/{id}/notifications
  • Auth
    • HTTP bearer
    • or API key in cookie accounts_superwall_token
    • or HTTP bearer

Path parameters

idstring required

Request body

channel'push' required

How to deliver it. Only push today: APNs for the project's iOS applications and FCM for its Android applications, chosen per application by the credentials it has (an APNs key, a Firebase service account). One send reaches every platform the target's devices are on.

dataSuperwallApiSchemaV2JsonObject1

Custom keys. iOS: placed at the top level of the APNs payload. Android: sent as FCM data, whose values are strings, so a non-string value is JSON-encoded (3 arrives as "3", {"a":1} as its JSON text). Reserved, and answered with 400: aps, sw and deep_link (Superwall's), and FCM's from, notification, message_type and every key starting google. or gcm.. The reserved keys apply to every send, including a project with only iOS applications: one send can reach both platforms.

ttl_secondsinteger

How long APNs or FCM keeps trying to deliver to a device that is offline, in seconds (iOS: apns-expiration; Android: android.ttl). Default 86400, at most 2592000. On Android FCM keeps a message at most 28 days (2,419,200 seconds), so a longer value is capped to that. 0 delivers only if the device is reachable now.

priority'high' | 'normal'

high delivers immediately (iOS apns-priority: 10, Android android.priority: HIGH), normal lets the device save power (5, NORMAL). Defaults to high, or normal for a background notification, which must be normal.

collapse_idstring

A newer notification with the same id replaces this one on the device (iOS apns-collapse-id, Android android.collapse_key). At most 64 bytes. FCM keeps at most 4 different collapse keys per device at a time, so use only a few distinct values.

thread_idstring

iOS only: groups notifications on the device (thread-id).

interruption_level'passive' | 'active' | 'time-sensitive'

iOS only (interruption-level).

content_availableboolean

Wakes the app in the background (iOS content-available). With no title, subtitle, body, badge or sound it is a background notification, which reaches devices whose notification permission is off. On Android a notification with no title or body is always a data-only message, delivered to the app without showing anything.

apnsSuperwallApiSchemaV2JsonObject2

iOS only: raw aps keys, merged over the ones built from the fields above. Use content_available, not content-available.

androidSuperwallApiSchemaV2JsonObject3

Android only: raw FCM AndroidConfig keys (snake_case), merged over the ones built from the fields above. A key replaces the built one whole: a raw notification replaces the built sound and notification_count. Refused with 400: data, ttl, priority, collapse_key, collapseKey, which Superwall sets from data, ttl_seconds, priority and collapse_id (an android.data would replace the message's data, and with it the key Superwall tracks opens by). A raw notification does not count as content: a send still needs a title, subtitle, body, badge or sound, or content_available: true (which makes it a background notification on iOS). notification.click_action opens a different activity when the user taps the notification; the app must call Superwall.handleNotificationOpen(intent) from whichever activity handles the tap, or Superwall never sees the open.

idempotency_keystring required

Your unique key for this send. Sending the same key again within 30 days returns the original response without sending again; the same key with a different body answers 409.

Example request

{
  "target": {
    "app_user_id": "user_8812"
  },
  "notification": {
    "sound": "default",
    "deep_link": "myapp://offers/spring"
  },
  "idempotency_key": "spring-offer-2026-user_8812"
}

Response

NotificationSendResponse

idstring required

The send's id (nsend_ and 26 characters), reported back in the sw.sendId key of the payload and in every event and webhook about this send.

status'queued' required

queued: the send was accepted and will be delivered to the target's devices. Each device's outcome is reported later as a notification_send / notification_fail event and a NOTIFICATION_SENT / NOTIFICATION_FAILED webhook.

Changes