Skip to main content

Push device tokens and scheduled sends

Two management surfaces under Messages → Push → Manage cover push operations after integration: the Device Tokens page (the registered-token inventory for your tenant) and the Scheduled pushes page (the queue of sends waiting for their scheduled time). Both are available to members with the owner, admin, or developer role. This guide covers what each page lists, how tokens move through their lifecycle, how the scheduler dispatches queued sends, and the matching API calls with runnable examples. Set up registration and sending first with the push integration guide; curated notification categories are covered in push notification categories. This page is about operating what those flows create.

1. Inspect the token inventory

The Device Tokens page lists every token registered in your tenant, newest first. Each row carries:
  • Platformios, android, huawei, or web.
  • Owning user — the user_id the token is scoped to, so you can tell which customer the device belongs to.
  • Install identityapp_install_id and device_id when the SDK supplied them, which lets you spot duplicate rows from reinstalls.
  • Timestampscreated_at (first registration) and last_seen_at (latest re-registration).
  • Delivery state — the enabled flag. A disabled token stays on file but is skipped by every send.
The same inventory is available over the API, filtered to one user when you pass user_id:
The list is capped at 200 rows per call, newest first — use the user_id filter when a tenant holds more devices than that.

2. Token lifecycle: arrival, staleness, revocation

Arrival. A token appears when a client registers it with POST /api/v1/push/device-tokens — usually from the SDK at first run and again on every OS token refresh. Registration is idempotent: re-registering the same token refreshes last_seen_at instead of creating a duplicate. When the client passes a stable app_install_id and the OS rotates the token on reinstall, the install’s previous row is retired automatically, so one device never keeps two live tokens. Staleness. A token goes stale when the app is uninstalled, the user revokes notification permission, or the OS replaces the token and the client never re-registers. FCM, APNs, and Web Push report this back as delivery feedback — an Unregistered, BadDeviceToken, or 410 Gone style rejection. Orbit treats those provider responses as permanent: the failing token is deleted from your inventory at send time, so the next send does not retry a dead device. Tokens that merely stop re-registering show their age through last_seen_at — a token untouched for weeks while the user stays active elsewhere is a candidate for cleanup. Revocation. Two controls, depending on intent:
Disable when a user signs out or a device misbehaves and you may want it back; delete when the token is unrecoverable or you are pruning. Deletes return 204 on success and 404 when the id is unknown.

3. Scheduled pushes: review and cancel the queue

Every scheduled push is one-off: you enqueue it by supplying a future send_at (ISO-8601 with offset) on POST /api/v1/push/send, and it returns 202 with the scheduled push id instead of dispatching immediately. To model a recurring send — a weekly digest, a daily reminder — enqueue each occurrence as its own scheduled row from your own cadence (for example, a campaign or journey step); each appears in the queue individually and can be reviewed or cancelled on its own. The dispatch sweep claims due rows roughly once a minute and replays the stored payload through the same send path an immediate send takes — so targeting, suppression, and frequency caps apply identically. A failed dispatch retries with exponential backoff; after five attempts the row is marked failed with the last recorded error, so you can inspect what went wrong instead of the send firing forever. The Scheduled pushes page lists the queue, soonest send_at first. Filter it by status over the API — scheduled, sent, cancelled, or failed:
Read a single row — including its full payload, attempt count, and last error — before it dispatches, or to see why one failed:
Cancel a row while it is still scheduled. Cancellation is a guarded status change, not a hard delete — once the dispatch sweep has moved the row to sent or failed, the cancel returns 409 SCHEDULED_PUSH_NOT_CANCELLABLE rather than silently succeeding:

4. API surface summary

Token operations: Scheduled-send operations: Writes (register, enable/disable, delete, enqueue, cancel) require the owner, admin, or developer role — the same gate the dashboard pages apply.

5. Best practices

  • Prune before big sends. Broadcasts are capped at 100,000 deliverable tokens and per-device failures count against your deliverability. Delete tokens the providers have flagged dead and disable tokens from churned installs before a campaign — the broadcast only counts enabled, unsuppressed tokens, so cleanup directly protects headroom.
  • Register with app_install_id. A stable per-install id is what lets a reinstall retire the old token instead of doubling the inventory. The push integration guide covers the registration call.
  • Re-register on every OS token refresh. That refresh stamps last_seen_at, which is also your signal for which rows have gone quiet.
  • Read the error before retrying a failed scheduled push. The last_error and attempt count on the row tell you whether the failure is a bad target (fix the payload and enqueue a new send) or a transient provider blip (cancel and re-enqueue if you no longer want it).
  • Cancel rather than let a stale announcement fire. If a queued promotion or announcement no longer makes sense when its time arrives, delete it while its status is still scheduled.
  • Curate the send shape, not just the queue. When your scheduled sends reference a named category for sounds, actions, or the Android channel, manage those centrally as in the push notification categories guide.