Push Scheduling
How Amba runs scheduled pushes — delays, retries, idempotency, and delivery windows.
When you schedule a push, Amba takes care of waiting until the right moment, retrying transient failures, and recording per-token delivery results. You don't manage timers or job queues — schedule the campaign and Amba handles delivery.
What Amba does for a scheduled campaign
When you POST a campaign with scheduled_at, or call /send, the API:
- Atomically marks the campaign row (
scheduledorsending). - Schedules delivery on the campaign's
scheduled_at. - Returns to the caller. The rest happens in the background.
When the scheduled time arrives:
- The target segment is resolved.
- Active push tokens for matching users are fetched.
- Users are sent in batches.
- One row per token is written to
push_deliverieswith status, provider message id, and error detail on failure. - The campaign is marked
sent.
Trying to schedule the same campaign twice raises 409 ALREADY_SCHEDULED — delivery is idempotent and double-dispatch is impossible.
Scheduling with scheduled_at
scheduled_at is a UTC ISO-8601 timestamp. The API rejects past and unparseable values:
The campaign row is inserted with status = 'scheduled'. Amba fires delivery at the caller's intended time without drift from API-side latency.
Cancelling a scheduled push
There is no DELETE /admin/push/:id today. To kill a scheduled campaign before it fires, contact support. The row stays at scheduled; you can flip it manually if needed.
Trying to /send a scheduled campaign returns 409 ALREADY_SCHEDULED — delivery is already on the way.
Retries and idempotency
Delivery is retried automatically:
- Transient APNs / FCM 5xx → retried with backoff, bounded by max-attempts.
BadDeviceToken/Unregistered→ the token is marked inactive, no retry (permanent).- Workflow-level failures roll the campaign status to
failedso operators see it.
Replaying /send on a failed campaign re-attempts delivery cleanly — the campaign id makes sends idempotent.
Per-project fan-out
Every campaign runs against exactly one project's data. There is no cross-project query. Hot projects are kept in memory so repeated campaigns don't pay a cold-start cost.
Delivery windows
There is no "quiet hours" feature at the protocol layer. To implement user-local delivery windows, schedule the campaign at the earliest UTC time that satisfies the window for every target timezone, or batch per-timezone campaigns. A first-class delivery-windows feature is on the roadmap.
Observability
Per-token delivery rows land in push_deliveries with status (sent / failed), provider_message_id, and error_message on failure. Query that table directly when you need a user-level audit trail.