Rate Limits
Orbit enforces rate limits to ensure platform stability and fair usage. Limits are applied per API key at the endpoint level, and the same limits apply to every account. If your integration needs more throughput, we can raise a limit with a per-organization override — there is no separate plan tier to upgrade to. See Requesting Higher Limits.Overview
Every API response includes rate limit headers:
When you exceed a rate limit, Orbit returns
429 Too Many Requests with the RATE_LIMITED error code.
Limits by Endpoint
Messaging
These per-channel send limits are the defaults that apply to every account. If your SMS (or any other channel) volume needs more headroom, we can raise the limit for your organization with a per-organization override — see Requesting Higher Limits.
Voice
Agents
These are platform-wide API limits on how often you can call the Agents endpoints. To cap how often a specific agent can be invoked overall or by a single caller — a separate, per-agent setting — see Agent cost controls → Invocation rate limits and quotas.
Numbers
Contacts & Campaigns
Billing & Webhooks
Worked Example: Read the Headers
Before you write retry logic, look at what the API actually returns. Every response — success or 429 — carries the three rate-limit headers from the table above, so you can track consumption and react before you’re rejected.Watch a full window with curl
GET /api/v1/messages has a 120/min limit. Run it twice with -i (include response headers) and read the consumption:
X-RateLimit-Remaining ticks down on every request in the window; X-RateLimit-Reset is the Unix timestamp when it refills. When a burst takes you past the limit — this burst repeats GET /api/v1/messages — the 429 tells you exactly how long to wait:
Retry-After (or x-ratelimit-reset minus now, if you only have the limiter headers) and sleep until it:
Typed SDK reads of the same headers
The raw response headers are exposed on every SDK — here is the same header capture in three languages, each hitting a different limit tier from the tables above:- Node
- Python
- Go
Header names are case-insensitive on the wire; each SDK surfaces them through its own response object. The escape hatch (
orbit.request / client.request / client.Request…) is shown because the header read is the point, not the typed wrapper — scope per language is on the SDK index.Handling Rate Limits
Best Practices
- Check headers proactively. Monitor
X-RateLimit-Remainingand slow down before hitting zero. - Implement exponential backoff. When receiving a
429, waitretry_afterseconds, then retry with increasing delays. - Queue and batch. For high-volume sends, queue messages and send in controlled batches.
- Use webhooks instead of polling. Subscribe to status webhooks rather than polling
GET /api/v1/messages/{id}.
Bounded retry wrapper
A bounded wrapper honors the server’sRetry-After (or error.retry_after) before falling back to a capped exponential, and gives up after a fixed attempt count so a stuck limiter can’t loop forever. This is the same pattern as the error-handling-by-example wrapper, applied here to sends:
- JavaScript
- Python
- Go
Global Per-Second Limit
In addition to the per-minute endpoint limits above, a single global limiter caps every API key at 50 requests per second as a platform safety net. This ceiling is applied uniformly to all callers regardless of plan — it is not a separate per-plan tier and there is no burst queue. Requests beyond 50 req/sec receive429 Too Many Requests immediately; they are not queued or delayed before rejection. In practice the per-minute endpoint limits above are the binding constraint for normal usage, so this global ceiling is rarely the limit you hit first. Apply the same exponential-backoff handling described above when you do.
Why your plan page shows a higher number
Your plan page (the Plan step in onboarding, and the Billing → Plan view) lists a “Sustained API requests per second” figure — 1,000 req/sec by default on the pay-as-you-go plan. That number is your organization’s configured capacity entitlement, tracked for account provisioning and future capacity planning — it is not a second, lower rate limit you can hit before the global ceiling above. The 50 req/sec limiter described in this section is the one number that actually returns429s, uniformly, for every account. If you need your plan’s entitlement raised to match higher sustained throughput, request it the same way as any other limit increase — see Requesting Higher Limits.