- 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.
POST /notifications(create) andDELETE /notifications(cancel) count toward the same rate limit.
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 / Cancel message | Free plans: 150 requests/sec/app Paid plans: 6,000 requests/sec/app The POST /notifications and DELETE /notifications endpoints share the same limit. Requests count toward it regardless of method. For example, 3,000 creates + 3,000 cancels = 6,000 requests/sec on a paid plan.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. These are 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 | 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
support@onesignal.com.
FAQ
Do API rate limits disable my app?
No. API rate limits (429 errors) only throttle your requests temporarily. Only application message limits — which track the total volume of messages delivered — can disable your app.
What is an idempotency key and when do I need one?
An idempotency key is a unique identifier you include with a request so that retrying the same request does not create a duplicate message or event. You need one whenever you retry aPOST /notifications or custom event request. Reuse the same key for every retry attempt. See Idempotent API requests.
Can I increase my API rate limit?
Paid plans have higher rate limits (6,000 requests/sec vs. 150 for free plans). If you need limits beyond the paid tier, contactsupport@onesignal.com with your use case and expected volume.
Why was my app disabled even though I didn’t hit the API rate limit?
API rate limits and application message limits are separate. Your app can be disabled if the total number of messages delivered in any 15-minute window exceeds 10× your subscription count — even if every individual API request succeeded. Common causes include retry storms, runaway automations, or targeting a larger audience than intended.Related pages
Idempotent API requests
Prevent duplicate messages by reusing idempotency keys on retries.
Create message API
API reference for sending push, email, SMS, and in-app messages.
Create custom event API
API reference for sending custom events that trigger Journeys.
Subscriptions
Understand how subscriptions are counted toward message limits.