Environment variables
Without
API_KEY / APP_ID the client degrades to log-only (does not throw)
and the health probe reports the component as down.Idempotency, retries and observability
- Idempotency: the consumer uses
queue_event_idasqueue_event.source_event_id; a duplicate redelivery is a no-op. - Retries: exponential backoff on transient (5xx / network) errors.
NonRetryableNotificationErrorbecomes a logged skip with no retry. - Event types: segmented by channel
(
vercel_queue.notification.push|in_app|sms|live_activity,…unifiedfallback). - Success context: handlers return
context.oneSignalIdfor correlation.
Runbook — DLQ and replay
Failures that exhaust retries land in the shared DLQ infrastructure (queue_dead_letter + queue_replay_job).
1
Detect
Query
queue_dead_letter filtering by
event_type LIKE 'vercel_queue.notification.%'.2
Diagnose
Review
queue_event_attempt (last error) and handler logs by
correlation / queue_event_id.3
Fix the root cause
OneSignal credentials, phone number or payload.
4
Reprocess
Enqueue a
queue_replay_job for the affected queue_event rows.5
Verify
The row moves to
processed with context.oneSignalId.Forcing an invalid API key in dev is the fastest way to observe the
retry → DLQ → replay cycle end-to-end.
Health
A cheap active probe (GET /apps/{app_id}, without consuming quota) combined
with real traffic paints the INTEGRATION_ONESIGNAL heartbeat on the status
page.
Mobile integration checklist
1
Initialize the SDK
Use the environment’s OneSignal App ID.
2
Bind the user
On authentication call
OneSignal.login(auth.users.id) to set the
external_id.3
Render in-app
Handle the data-only push of the
in_app channel.4
Register phone
Persist the user’s E.164 phone for SMS.
5
Respect preferences
Read
GET /v3/notification/preference/me and persist changes with
PUT/PATCH .../me.