Skip to main content
Send Push Notification
Fans a push notification out to every registered device binding belonging to the listed users. The server dispatches to APNs (iOS), FCM (Android), and the Web Push protocol in parallel, using whichever platform credentials are configured for this project. Requires a service or master key (Authorization: Bearer <serviceKey>). End-user tokens are rejected — this endpoint is intended for your backend, not for end users calling it directly. Requires the push bundle.

Body Parameters

string[]
required
Array of Sublay user IDs to notify. Between 1 and 100 IDs per request.
string
required
Notification title. Displayed as the bold heading on the device.
string
required
Notification body text.
object
Optional key-value data payload forwarded to the app alongside the notification. Values must be strings or serializable primitives. Use this to pass deep-link targets, IDs, or any context your app needs when the user taps the notification.recipientUserId is reserved. The server stamps every dispatched copy with the id of the account that copy is for, so a device signed into several accounts can tell which one a notification belongs to. A value you supply under that key is overwritten — an account-routing key has to be trustworthy.
One notification per account, not per device. A physical device can be bound to several accounts at once. If two of the userIds are signed in on the same device, that device receives two notifications — one per account, each with its own recipientUserId.

Rich payload fields

All optional. Each is mapped to whichever platform(s) support it at dispatch time and silently ignored on platforms that have no equivalent. See the Push Notifications guide for the client-side setup some of these require (Android channels, the iOS Notification Service Extension, your web service worker).
string
Sound file to play. iOS: APNs sound. Android: governed by the channel on 8+ — pair with channelId. Web: forwarded to the service worker.
number
iOS app-icon badge count (APNs badge). No Android equivalent. The caller supplies the number; Sublay tracks no unread state.
string
Android notification channel id (FCM android.notification.channel_id). The channel must be created client-side; on Android 8+ it owns sound/importance/vibration.
string
"high" or "normal". iOS: APNs apns-priority (10/5). Android: FCM android.priority. high wakes the device for time-sensitive pushes. Defaults to high when omitted.
string
iOS subtitle line under the title (APNs alert.subtitle).
string
Rich/big-picture image URL. Android (FCM image) and Web work out of the box. iOS additionally requires a Notification Service Extension in the app — the URL is forwarded in the payload and mutable-content is set automatically.
string
Display-replace key so notifications collapse in the UI (FCM android.notification.tag, Web tag). Scoped per recipient, exactly like collapseId below.The device receives a different string than you sent. Scoping appends ~ and a short digest of the recipient’s user id, so a push sent with tag: "thread-42" arrives carrying something like thread-42~9f3c1a8b. Client code that reads the delivered tag — a service worker matching open notifications, for instance — must not compare it to the value it sent. Match on a prefix, or carry your own key in data instead, which is passed through untouched.
string
Transport-level collapse identifier (APNs apns-collapse-id, FCM collapse_key) — a newer push supersedes an undelivered one carrying the same id for the same account.Scoped per recipient. Two accounts signed in on one physical device share one transport destination, so the server appends a short digest of the recipient’s id to the key you supply before handing it to the provider — the provider therefore sees a different string than you sent. Each account gets its own collapse namespace on the shared device and cannot supersede the other’s notification, while collapsing within a single account behaves exactly as the field describes.Over-length keys are folded rather than refused. APNs caps apns-collapse-id at 64 bytes. When your key plus the recipient digest would exceed that, the server replaces the whole scoped key with a fixed-width digest of it — still deterministic and still per-recipient, so collapsing keeps working — instead of letting APNs reject the send with BadCollapseId. FCM’s collapse_key and the display tag have no comparable documented ceiling, so nothing is folded on those paths. The parameter itself has no maximum: any non-empty string is accepted.
string
iOS notification grouping (APNs thread-id).
number
Time-to-live in seconds for offline devices (APNs apns-expiration computed from now, FCM android.ttl).
boolean
iOS mutable-content flag, enabling the app’s Notification Service Extension to modify the payload (e.g. attach imageUrl). Set implicitly when imageUrl is provided.

Response

Returns 200 with a results map keyed by user ID. Every requested userId is present in the response — users with no registered devices get an empty array rather than being omitted.
object
Map from user ID to an array of per-device delivery results.
Tokens or subscriptions reported as permanently invalid by the upstream provider (e.g. APNs BadDeviceToken, FCM UNREGISTERED, Web Push HTTP 410) are automatically deleted during the send — no separate cleanup step is needed. A dead token is dead for the whole device, so every account bound to it is unbound, including accounts that were not part of this request.

Error Responses

Returned when userIds is empty, exceeds 100 entries, or required fields are missing.
Returned when called with an end-user access token instead of a service/master key.
Returned while the push bundle is mid-install. Retry shortly.
The fan-out itself failed. Nothing beyond this code is returned. Note that a failure while pruning dead tokens after delivery does not reach here — the pushes were delivered and the response is still 200.
Rate limit: 50 requests per 5 minutes per IP. Exceeding it returns 429 with a plain-text message and no code.

See Also