The Light API limits how many requests each integration can make, to keep it fast and fair for everyone. Every authenticated response tells you where you stand, and a request over the limit gets a 429 Too Many Requests response.
Rate limits apply to API keys, OAuth tokens and MCP tokens.
Rate limit structure
Two limits apply by default, and every request is checked against both. A request goes through only when both allow it. Light can agree different limits with your company.
Requests per minute
- 300 requests per minute per credential.
- The allowance refills continuously, at 5 requests a second with the default limit, rather than all at once at the top of each minute. When the allowance is full you can send a burst of up to 300 requests at once.
- Each API key has its own per-minute allowance. OAuth tokens issued to the same person share one allowance between them.
Daily limit
- 100,000 requests per day per organisation.
- Shared by every API key, OAuth token and MCP token in your organisation, so extra API keys add per-minute room but never daily capacity.
- Resets at midnight UTC.
Reading the headers
Every authenticated response carries these headers, whether it succeeded or failed:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
The size of the window the headers describe (300 or 100,000 by default) |
X-RateLimit-Remaining |
Requests left in that window |
X-RateLimit-Reset |
Unix timestamp, in seconds, when that window is back to full capacity |
The three headers describe one window at a time: whichever of the two has fewer requests remaining. Normally that is the per-minute window. Once the daily count left drops below the per-minute count left, they switch to the daily window. The X-RateLimit-Limit value tells you which one you are looking at.
X-RateLimit-Reset is when the window is completely full again (the per-minute allowance fully refilled, or midnight UTC for the daily limit). It is not the moment the next single request would be accepted, which for the per-minute window is usually much sooner.
Handling a 429
A 429 has a flat { "type": "TOO_MANY_REQUESTS", "message": "Rate limit exceeded" } body, described with the other error shapes in Pagination, filtering and errors. It also carries a Retry-After header, which is only sent on a 429:
| Header | Meaning |
|---|---|
Retry-After |
Whole seconds to wait before retrying |
Retry-After is worked out from the same timestamp as X-RateLimit-Reset, so for the per-minute limit it is conservative and a retry may succeed sooner. A refused request does not use up any of your allowance.
Best practices
- Watch the headers on every response. Slow down as
X-RateLimit-Remaininggets low, instead of waiting for a429. - Back off exponentially. Wait progressively longer between retries: 1s, 2s, 4s, 8s.
- Respect
Retry-After. Always wait at least that long before retrying. - Spread out scheduled jobs. Avoid running every batch operation at the same time.
Concurrent call limits
Separately from the rate limits, a few endpoints allow only a small number of calls in flight at once per credential. Their endpoint pages say so. Going over returns a 429 with the type CONCURRENCY_LIMIT_EXCEEDED. It has no Retry-After header and does not change the X-RateLimit headers. Wait for one of your running calls to finish, or retry after a short pause.
The MCP server reports throttling differently, as an error inside a 200 response. See Using Light from an AI client.
Sandbox limits
The sandbox environment runs with much higher limits: 10,000 requests per minute and 1,000,000 per day. An integration tested only against the sandbox will not meet the production limits until it goes live. Test your handling against the header values rather than waiting to see a 429.
Need higher limits?
If your use case requires higher rate limits, contact Light support at help@light.inc to discuss custom limits for your organisation.