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 noto / 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).
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:
ios—sound,badge,category,thread_id,interruption_level,relevance_score,mutable_content,image_url,apns_collapse_id,apns_priority,apns_expiration.android—channel_id,priority(normal·high),ttl_seconds,image_url,notification_count,color(#RRGGBB).webpush—icon_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). Atopicwith disallowed characters or more than 2actionsis rejected with HTTP422.
Scheduled send
Supplysend_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 returns201 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):
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 ofuser_ids, or broadcast to every opted-in device withuser_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
dataobject (< 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 events —
push.deliveredandpush.openedwebhook 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.
-
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>.p8file. Apple lets you download it once — store it in your secret manager immediately. -
Configure the environment — set all four variables.
DEVOTEL_APNS_KEY_ID,DEVOTEL_APNS_TEAM_ID, andDEVOTEL_APNS_PRIVATE_KEYmust be set together; if any is missing every targeted iOS device returnsstatus: "failed".When the trio is unset, each targeted iOS device returnsstatus: "failed"with codeMESSAGE_SEND_FAILEDand the messageAPNs credentials not configured …. - 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 byNODE_ENVfirst: whenNODE_ENV=productionthe platform always targets the production host, andDEVOTEL_APNS_PRODUCTIONhas no effect.DEVOTEL_APNS_PRODUCTION=trueonly forces the production host under a non-productionNODE_ENV. Consequently you cannot test a sandbox (development-build) token against a production deployment — it will be misrouted to the production host and rejected withBadDeviceToken. 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.-
Generate the keypair — run once and keep the output:
This prints a base64url public key and a private key.
-
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 innotifications[]comes back withstatus: "failed"and an error noting Web Push is not configured. Native (APNs / FCM) targets in the same send are unaffected. -
Browser registration — the web SDK calls
OrbitPush.isSupported()and thenpushManager.subscribewith 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 OAuth2client_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.
- 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.
-
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. -
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
- Integrate the Devotel mobile SDK (
@devotel/orbit-mobile) or the web SDK (@devotel/orbit-web). - 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. - 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.