Skip to main content

Overview

When you create messages or custom events via our REST API, network failures or timeouts can cause uncertainty about whether a request succeeded. Idempotent requests solve this problem by ensuring the same request is only processed once—even if it is sent multiple times. This page explains how idempotency works in OneSignal, when to use it, and common pitfalls to avoid.

When you should use idempotency

You should use idempotent requests any time you plan to retry API calls, especially when:
  • You receive a timeout, 500-level error, or no response.
  • Your infrastructure automatically retries failed requests.
  • Delivering a duplicate message or custom event would be harmful.
  • Missing a message or custom event would be harmful.

The problem idempotency solves

Consider this common failure scenario:
  1. You send a notifications#create or custom_events#create request.
  2. OneSignal begins processing and sending the message or event.
  3. A network error occurs before your client receives a response.
At this point, your system cannot know whether the request succeeded.
  • If you retry and the request already succeeded, users may receive duplicates.
  • If you do not retry and the request failed, users may miss important messages or events.
Idempotency provides a safe retry mechanism.

How idempotency works

OneSignal supports idempotent operations for: You provide a unique idempotency_key with each request.

Request flow with idempotency

  1. You send a request with an idempotency_key.
  2. OneSignal processes the request and begins sending the message or creating the custom event.
  3. A network error or timeout occurs.
  4. You retry the request using the same idempotency_key.
  5. OneSignal detects the duplicate and returns the result of the original request.
  6. Only one notification or custom event is processed.
You can repeat this retry any number of times. As long as the idempotency_key remains the same, the operation will only be processed once.

Idempotency key reference

idempotency_key
RFC 9562 UUID
A unique identifier used to prevent duplicate messages or custom events from repeat API calls. Keys must be unique RFC 9562 UUID format. Valid for 30 days.
This idempotency_key property used to be called external_id but caused confusion with our Users external_id alias, so we have added this new property name to reduce confusion. Both will work in this case.

Important constraints and gotchas

If you reuse the same idempotency_key for different messages or events, only the first request will be processed.
Keep the following in mind:
  • Keys must be unique per logical operation Generate a new UUID for every notification or custom event you intend to send.
  • Keys are retained for 30 days After 30 days, OneSignal may delete the record. Reusing the same key after that window may result in a new message being sent.
  • Use a strong source of randomness Predictable or reused UUIDs can cause unexpected deduplication.
  • Idempotency does not guarantee delivery It only guarantees at-most-once processing. You should still monitor API responses and logs.

Legacy behavior

The idempotency_key property was previously named external_id. This caused confusion with the Users external_id alias, so idempotency_key is now the recommended field name. Both names are currently supported.

Best practices

  • Always include idempotency_key when implementing retries.
  • Store the idempotency_key alongside your request metadata for debugging.
  • Retry only after honoring any Retry-After header returned by the API.
  • Combine idempotency with proper timeout handling (for example, a 60-second HTTP timeout).