Overview
OneSignal uses rate limits and error responses as safety mechanisms to protect your app from accidental overloads, duplicate sends, and retry storms. There are three categories to understand:- API rate limits return HTTP
429errors when request volume is too high. - Network timeouts or temporary server failures return
5xxerrors or no response at all. - Application message limits may temporarily disable your app if too many messages are sent in a short period.
Most apps never hit these limits during normal usage. When they do occur, they are usually caused by retries, loops, or unexpected audience expansion.
Quick implementation checklist
- Expect
429,5xx, and timeouts — they are normal at scale. - Never retry message sends without an
idempotency_key. - For non-urgent retries, wait 100 seconds before retrying.
- API rate limits (
429) never disable your app. - Only message volume limits can disable your app.
API rate limits
API rate limits apply per app and per endpoint. They are evaluated when a request is received, not when a response is returned. These limits are designed to throttle traffic, not block your app.| Endpoint | Rate limit |
|---|---|
| Create message | Free plans: 150 requests/sec/app Paid plans: 6,000 requests/sec/app Each request can target many users or segments. |
| Create, update, or delete users or subscriptions | 1,000 requests/sec/app 1 request/sec per user or subscription Up to 100 property updates per request |
| View endpoints (messages, templates, users) | 1 request/sec/app Up to 10 look-back requests/sec |
| Message History and CSV exports | Keep parallel exports under 100 GB per file |
High-volume messaging should use fewer message creation requests with larger audiences instead of increasing request frequency.
429):
When you exceed an API rate limit, OneSignal returns an HTTP 429 response:
Retry-After header indicating how many seconds to wait before retrying.
What to do when you receive a 429 error:
- Stop sending requests immediately.
- Wait for the full duration specified in the
Retry-Afterheader. - Retry using exponential backoff.
- Always reuse the same
idempotency_keyfor retries that send messages.
Error handling and retry strategies
Retries are safe only when implemented correctly. Some failed requests may still be processing on our servers.- Retriable errors generally include network timeouts, no responses, 429, and 5xx errors.
- Non-retryable errors include 400, 401, or 403 errors which indicate invalid input, authentication problems, or missing permissions—not temporary failures.
- Wait 100 seconds before retrying.
- This aligns with the maximum API response timeout.
- If no response or network error occurs, the request may still be processing during this window.
- Retry up to 3 total attempts (original + 2 retries).
- Always reuse the same
idempotency_keyfor each retry.
- Retry using exponential backoff with jitter (for example: 2s, 4s, 8s… up to 60s).
- Cap retries to 10 total attempts and stop after 10–15 minutes.
- For
429responses, treatRetry-Afteras a minimum delay: waitmax(Retry-After, backoff). - Always reuse the same
idempotency_keyfor each retry.
Example retry logic
Example retry logic
Retry decision guide
| Error type | Retry? | When | Idempotency required |
|---|---|---|---|
429 Too Many Requests | Yes | After Retry-After | ✅ Yes |
5xx Server Error | Yes | Backoff or 100s | ✅ Yes |
| Timeout / no response | Yes | Immediate or delayed | ✅ Yes |
400 Bad Request | No | Fix request | ❌ No |
401 / 403 | No | Fix auth/permissions | ❌ No |
Application message limits (app disablement)
Application message limits protect your users from receiving too many notifications in a short period of time. How the limit works: In any rolling 15-minute window, you may send up to 10 × your total number of subscribed Subscriptions. This limit is based on the total number of messages delivered, not the number of API requests.- Sending 1 notification to 1,000 Subscriptions = 1,000 messages
- Sending 10 notifications to 1,000 Subscriptions each = 10,000 messages
- Messages are counted for 15 minutes after they are sent
- As time passes, older messages automatically stop counting
- You only exceed the limit if more than 10× your subscribed Subscriptions receive messages within the same 15-minute span
- App with 1,000 subscribed Subscriptions → up to 10,000 messages in any 15 minutes
- App with 10,000 subscribed Subscriptions → up to 100,000 messages in any 15 minutes
| Scenario | Maximum messages counted in any 15-minute period | App disabled? |
|---|---|---|
| At 12:00, send 1 notification to 1,000 users | 1,000 | ❌ No |
| At 12:00, send 10 notifications to 1,000 users | 10,000 | ✅ Yes (hits limit) |
| Between 12:00–12:14, send 10,000 notifications to 1 user | 10,000 | ✅ Yes (hits limit) |
| Send 9,000 messages at 12:00, then 9,000 more at 12:16 | 9,000 | ❌ No |
| Send 9,000 messages spread between 12:00–12:14, then send 9,000 more at 12:15 | ~18,000 | ✅ Yes (exceeds limit) |
This limit is evaluated continuously over a rolling 15-minute window, not in fixed time blocks. If any 15-minute span exceeds your limit, the app is disabled.
- Your app is temporarily disabled
- All app administrators receive an email notification
- A re-enable banner appears in the OneSignal Dashboard
- Pause message sending from your backend, jobs, or automations.
- Identify the cause, such as Infinite loops, Retry storms, or Unexpected segment growth.
- Log in to the OneSignal Dashboard.
- Click Re-enable in the red banner at the top of the app.
- If you need help re-enabling your app, contact
[email protected].
Next steps:
- Learn how to safely retry with Idempotent API requests
- Review Create notification API
- Review Create custom event API