Rate Limits
The exit1.dev API enforces rate limits to ensure fair usage and platform stability.
Read Limits
| Scope | Limit |
|---|---|
| Pre-authentication | 20 requests/minute per IP |
| Per API key | 5 requests/minute |
| Per endpoint (per key) | 1 request/minute |
| Daily per key | 500 requests |
| Daily per user | 2,000 requests |
“Per endpoint” means per route, not per check: GET /v1/public/checks/a and GET /v1/public/checks/b share one bucket, and so do toggling two different checks. This is on purpose. It keeps a script looping over many checks from turning into a burst of requests. These limits count every request, including writes.
To act on several checks in a row with an API key, space the calls a minute apart. For live status of every check, use /checks/status instead of fetching checks one by one.
Daily quotas are 24-hour windows that start with the first request counted against them, not calendar days.
Status Polling
GET /v1/public/checks/status has its own limits instead of the ones above, so a monitoring system can poll it every 10 to 30 seconds:
| Scope | Limit |
|---|---|
| Per API key | 6 requests/minute |
| Per user (all keys) | 12 requests/minute |
These requests do not count toward the daily quotas or the per-key limit of the other endpoints. The pre-authentication limit per IP still applies. Send If-None-Match with the last ETag to get a 304 when nothing changed.
Write Limits
Write endpoints (POST, PATCH, DELETE) have additional rate limits on top of the read limits:
| Scope | Limit |
|---|---|
| Per API key | 2 write requests/minute |
| Daily per key | 100 write requests/day |
| Daily per user | 300 write requests/day |
Check Creation Limits
Creating checks is further limited to prevent abuse:
| Scope | Limit |
|---|---|
| Per minute | 10 checks |
| Per hour | 100 checks |
| Per day | 500 checks |
These are anti-abuse limits, not plan limits. They apply on every tier and are separate from your plan’s monitor cap.
OAuth (MCP) Sessions
Requests made with an OAuth access token from the hosted MCP server use a more generous profile, since agent sessions are interactive:
| Scope | Limit |
|---|---|
| Pre-authentication | 20 requests/minute per IP |
| Per credential | 30 requests/minute |
| Per endpoint (per credential) | 10 requests/minute |
| Daily per credential | 1,500 requests |
| Daily per user | 3,000 requests |
| Writes per credential | 15/minute, 200/day |
| Writes per user | 400/day |
Rate Limit Headers
Responses include these headers:
| Header | Description |
|---|---|
RateLimit-Limit | Maximum requests allowed in the current window |
RateLimit-Remaining | Requests remaining in the current window |
RateLimit-Reset | Seconds until the current window resets (not a timestamp) |
RateLimit | The same three values combined, for example limit=1, remaining=0, reset=42 |
Retry-After | Seconds to wait before retrying. Only sent on 429 responses |
On successful requests the headers describe the per-endpoint limit. On a 429 they describe the limit that was exceeded.
Exceeding Limits
When you exceed a rate limit, the API returns a 429 Too Many Requests response with a retryAfter field (seconds):
{
"error": "Rate limit exceeded. Please try again later.",
"retryAfter": 42
}When a daily request quota is exceeded, the body also includes the quota and when it resets (epoch ms):
{
"error": "Daily quota exceeded for this credential. Limit: 500 requests/day. The window resets 24 hours after it started (see quotaReset).",
"quotaLimit": 500,
"quotaReset": 1736985600000,
"retryAfter": 31200
}Rely on quotaReset (or retryAfter) for the actual reset time: the window ends 24 hours after it started.
Write limit 429s include retryAfter but not quotaLimit or quotaReset. The check creation limits return only an error message.
Best Practices
- Cache API responses locally when possible
- Implement exponential backoff when receiving 429 responses
- Honor
Retry-After(orretryAfterin the body) instead of retrying blindly - Monitor the
RateLimit-Remainingheader to stay within limits - Spread requests evenly over time rather than bursting
- Use
limit=100on list requests to reduce the number of pages you fetch - Poll
/checks/statusfor live status instead of paging through the list - Use
ranges=on the stats endpoint to fetch several windows in one request - Use idempotency keys when retrying failed create requests