Skip to main content

Push Notifications

Orbit’s Push channel delivers notifications to iOS (APNs), Android (FCM), Huawei (HMS Push Kit), and Web Push (VAPID) subscribers from a single API surface. Token registration, capability flags (sound, badge, mutable-content), and per-device delivery results are surfaced through the same Messaging API used for every other channel.

Send a push

POST /api/v1/push/send fans a single notification out across every registered iOS / Android / Web device that matches the targets you supply.

Targeting

There is no to / from / topic field — provide exactly one of:
  • device_token_ids — array of registered device-token ids to deliver to specific devices.
  • user_ids — array of Orbit user ids; pass ["*"] to broadcast to every opted-in device in the tenant (subject to the broadcast recipient cap).
If neither is present the request fails validation with HTTP 422 (Either device_token_ids or user_ids must be provided). STOP / opt-out and disabled tokens are filtered server-side, so a broadcast only reaches deliverable devices.

Fields

title (1–500 chars) and body (1–4000 chars) are required; values outside those bounds are rejected with HTTP 422. Top-level rich-media and per-platform fields: Over-length or malformed values fail schema validation with HTTP 422; the offending field path is returned in error.details. Per-platform override objects fine-tune a single platform:
  • iossound, badge, category, thread_id, interruption_level, relevance_score, mutable_content, image_url, apns_collapse_id, apns_priority, apns_expiration.
  • androidchannel_id, priority (normal · high), ttl_seconds, image_url, notification_count, color (#RRGGBB).
  • webpushicon_url, image_url, actions ({ action, title }, at most 2, each string ≤ 64 chars), urgency, ttl_seconds, topic (must match ^[A-Za-z0-9_-]{1,32}$ — letters, digits, _ or -, 1–32 chars), require_interaction, tag (≤ 64 chars). A topic with disallowed characters or more than 2 actions is rejected with HTTP 422.

Scheduled send

Supply send_at (ISO-8601 with offset) to schedule the send. When it is strictly in the future the request returns 202 and the payload is replayed at send time; a value at or before now falls through to an immediate send.

Response

An immediate send returns 201 with a per-device result list. Each id is a push-notification id (push_ + 32 lowercase hex chars) and deviceTokenId is a registered device-token id (dtk_ + 32 lowercase hex chars):
A scheduled send (send_at in the future) returns 202 with a scheduled-push id (spush_ + 32 lowercase hex chars):

Capabilities

  • Multi-platform — APNs (iOS, macOS, watchOS, tvOS, visionOS), FCM (Android), HMS Push Kit (Huawei devices without Google Play Services), and Web Push (VAPID).
  • Device tokens or users — target explicit device_token_ids, a set of user_ids, or broadcast to every opted-in device with user_ids: ["*"].
  • Rich content — title, body, image, action buttons, deep-link data payload, badge, sound, channel id (Android), thread id (iOS).
  • Custom data payload — attach a data object (< 4 KB) that rides alongside the notification so your app can act on tap or on receipt.
  • Live Activities (iOS 16.1+) — start, update, and end Live Activity notifications with the activity-specific endpoint variant.
  • Delivery + open eventspush.delivered and push.opened webhook events when SDK is integrated.
  • Auto-token rotation on GKE — FCM service-account tokens are auto-refreshed via the GCE metadata server; no manual key management required.

Apple Push setup (APNs)

Native iOS push uses token-based (.p8) authentication. The platform signs an ES256 JWT from your APNs Auth Key on every delivery, so you configure four credentials on the API / push worker via environment.
  1. Create an APNs Auth Key — in the Apple Developer portal, go to Certificates, Identifiers & Profiles → Keys, create a key with the Apple Push Notifications service (APNs) capability, and download the AuthKey_<KEY_ID>.p8 file. Apple lets you download it once — store it in your secret manager immediately.
  2. Configure the environment — set all four variables. DEVOTEL_APNS_KEY_ID, DEVOTEL_APNS_TEAM_ID, and DEVOTEL_APNS_PRIVATE_KEY must be set together; if any is missing every targeted iOS device returns status: "failed". When the trio is unset, each targeted iOS device returns status: "failed" with code MESSAGE_SEND_FAILED and the message APNs credentials not configured ….
  3. Register device tokens — the mobile SDK registers each device’s APNs token (see Token onboarding); no per-device key setup is needed.
Sandbox vs production tokens are not interchangeable. A token minted by a development build only resolves against the sandbox host, while App Store / TestFlight tokens only resolve against the production host. APNs routing is driven by NODE_ENV first: when NODE_ENV=production the platform always targets the production host, and DEVOTEL_APNS_PRODUCTION has no effect. DEVOTEL_APNS_PRODUCTION=true only forces the production host under a non-production NODE_ENV. Consequently you cannot test a sandbox (development-build) token against a production deployment — it will be misrouted to the production host and rejected with BadDeviceToken. Test sandbox tokens against a non-production deployment instead.

Web Push setup (VAPID)

Web Push uses a single application-server VAPID keypair (RFC 8291 / RFC 8292) that the operator generates once and provides to the platform via environment.
  1. Generate the keypair — run once and keep the output:
    This prints a base64url public key and a private key.
  2. Configure the environment — set the three variables on the API / push worker: When these are unset the native channels still work, but a web-push delivery cannot complete: the send still returns 201, and that device’s entry in notifications[] comes back with status: "failed" and an error noting Web Push is not configured. Native (APNs / FCM) targets in the same send are unaffected.
  3. Browser registration — the web SDK calls OrbitPush.isSupported() and then pushManager.subscribe with the public key, registering the resulting subscription as a device token (see Token onboarding).
Rotating keys invalidates every existing browser subscription — clients must re-subscribe. Rotate only when the private key is compromised.

Huawei Push setup (HMS)

Huawei devices that ship without Google Play Services cannot receive FCM, so Orbit delivers to them through Huawei Push Kit (HMS). The platform authenticates with an OAuth2 client_credentials grant against oauth-login.cloud.huawei.com and sends through push-api.cloud.huawei.com, so you configure two credentials from AppGallery Connect via environment.
  1. Create an AppGallery Connect app — in AppGallery Connect, create (or open) your project and Android app, then enable Push Kit under Grow → Push Kit. The app’s App ID and App secret are shown on the project’s General information page.
  2. Configure the environment — set both variables on the API / push worker. They must be set together; if either is missing the HMS path is treated as unconfigured and the Huawei send fails (see details below). When both are unset the native and web channels still work, but a Huawei send fails with Huawei Push Kit not configured — DEVOTEL_HMS_APP_ID and DEVOTEL_HMS_APP_SECRET are required. iOS / Android / Web targets in the same send are unaffected.
  3. Register device tokens — register each Huawei device with platform: "huawei" and the raw HMS Push Kit registration token returned by the HMS SDK on the device (see Token onboarding). Push Kit access tokens are cached and refreshed automatically; no manual token management is needed.

Token onboarding

  1. Integrate the Devotel mobile SDK (@devotel/orbit-mobile) or the web SDK (@devotel/orbit-web).
  2. The SDK requests notification permission and registers the device token with POST /api/v1/push/device-tokens (alias: POST /api/v1/push/register) against the user’s Orbit identity.
  3. Tokens are scoped per (org, app, user) and rotated automatically on platform-token refresh.

Common errors

A per-device delivery failure (expired or unregistered token, a provider outage, or unconfigured Web Push) is not a top-level error: the send returns 201 and the affected device appears in notifications[] with status: "failed" and an error string. Tokens the platform reports as permanently gone are removed automatically, so the next send skips them.

Pricing

Push delivery itself is free of carrier fees. Orbit charges a per-1M flat platform fee for fan-out. See the pricing page.