- 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.- The Create custom events endpoint has its own rate limit, separate from the notification endpoints.
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 custom events | Rate-limited independently from Create Message. Request size limits: 2,024 bytes per event · 1 MB per request body |
| 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.