Skip to main content

Push broadcasts: setup and pre-send caps

A push broadcast is a wildcard send — user_ids: ["*"] on POST /api/v1/push/send — that fans one notification out to every opted-in device in your tenant. Run this checklist once, before the first wildcard send, so the two pre-send gates (audience size, per-minute rate) never trip on a live campaign. Each step below is a tenant-owned control you configure once; nothing on this page is platform-internal.

1. Provider credentials

Orbit holds your provider credentials and fans a send out to the right transport from the single POST /api/v1/push/send endpoint. Configure each provider you need — a send fans out per-device, so an iOS-only tenant needs only APNs, and unconfigured providers return per-device status: "failed" entries rather than a top-level error. Bring-your-own credentials cover all four providers in the same channel, and the per-send pricing page still shows a flat platform fee — no per-push provider charge on the unified send. The detailed table per provider, with the exact variable names and where to source each value, lives on the Push channel reference (sections Apple Push setup, Google / FCM, Web Push setup, and Huawei Push setup).
Rotate only when a key is compromised. Rotating APNs / VAPID / HMS credentials invalidates every existing subscription — end users must re-subscribe. FCM access tokens rotate automatically (GKE metadata-server tokens refresh on a 1-hour TTL); no manual action is needed on GKE.
Validate the full chain end-to-end with POST /api/v1/push/test-send: it fires one fixed test notification to your own registered devices and returns a per-token verdict per provider — never a broadcast, and never counted as a tracked send.

2. Payload shape per provider

One request shape covers every provider; the per-platform override objects fine-tune a single transport without forking your send code.
Key rules per provider:
  • APNs (iOS) — title (≤ 500) + body (≤ 4000) are required; badge, thread_id, interruption_level, relevance_score, and mutable_content map straight onto the APNs payload; keep the whole payload under the 4 KB provider cap.
  • FCM (Android) — channel_id picks the Android notification channel, priority is normal or high, and ttl_seconds bounds how long FCM stores an offline device.
  • Web Push (VAPID) — topic must match ^[A-Za-z0-9_-]{1,32}$, and actions is capped at 2 per RFC 8294; a topic with disallowed characters is rejected with HTTP 422 before the provider is ever called.
The full field table with every per-platform override lives on the Push channel reference.

3. Broadcast caps (pre-send gates)

Two gates refuse a broadcast before dispatch — neither reaches the provider, no wallet hold is taken, and both are deterministic (retrying the identical shape computes the same refusal). Read the error.details envelope to tell which gate fired. Fix the gate at its own surface — split a 422 into explicit user_ids batches, or throttle / raise the push override for a 429. The full refusal-decoding runbook, with the details envelope shapes and the recovery sequence, is the push broadcast pre-send gates page.

4. Device-token lifecycle and pruning

Device tokens are the audience a broadcast counts; keep them current or the audience gate over- or under-counts.
  1. Register once per (org, app, user) — the mobile SDK (@devotel/orbit-mobile) or web SDK (@devotel/orbit-web) calls POST /api/v1/push/device-tokens with the device’s APNs / FCM / VAPID subscription. Re-registering the same token is an idempotent upsert — it refreshes last_seen_at and never duplicates the row.
  2. Rotate automatically — the SDK hands a refreshed platform token to the same endpoint; the platform resolves the rotation server-side.
  3. Prune dead tokens — a token the provider reports as permanently gone (APNs 410, FCM UNREGISTERED) is removed automatically on the delivery path, so the next send skips it. Disable a noisy device without deleting it via PATCH /push/device-tokens/:id (enabled: false), or delete outright via DELETE /push/device-tokens/:id.
The audience gate counts only deliverable tokens — active suppression and disabled rows never count — so pruning keeps your broadcast-size estimate honest.

5. Delivery receipts

A send returns 201 immediately with a per-device verdict array; durability lives in the delivery log, not the send response.
  • Per-device verdicts — each entry in notifications[] carries status (sent / failed / skipped), delivered_at, opened_at, and any provider error. total and sent aggregate the page.
  • Delivery log — page through GET /api/v1/push/notifications with a cursor to reconcile a broadcast after the fact.
  • Webhooks — when the SDK is integrated, push.delivered and push.opened fire as webhook events so your pipeline gets receipts without polling.
Decode per-device failures (token expiry, unconfigured provider, VAPID rotation) on the push token expiry runbook.

6. When to prefer push vs SMS or the inbox

Push is the right surface for your installed base (no carrier cost, per-device receipts, capability flags like badge / sound / mutable-content). SMS still wins for reach across phone numbers, and the inbox wins when the user needs to reply.

See also