Rate limits and concurrency
Rate limit
Requests are counted per account in a one-second window; X-RateLimit-Limit on every response is your limit. Short bursts up to one second's worth
are admitted. Over the limit you get 429 RATE_LIMIT_EXCEEDED without Retry-After; it clears within a second.
Concurrency
Concurrency slots bound how many jobs run at once. A synchronous monitor call takes a slot for its whole run, or fails at once with
429 CONCURRENT_LIMIT_EXCEEDED (details.limit is your limit) when every slot is busy. An async task takes a slot only when it starts;
until then it waits in your queue. Synchronous calls and async tasks share the same slots, and a task waiting to retry keeps its slot.
Accounts take turns for workers, so another account's large batch does not hold up yours. Slots per plan:
| Plan | Concurrent jobs |
|---|---|
| Free | 1 |
| Lite | 10 |
| Hobby | 20 |
| Starter | 50 |
| Growth | 75 |
| Business | 100 |
| Enterprise 2K | 135 |
| Enterprise 3K | 175 |
| Enterprise 4K | 215 |
| Enterprise 5K | 255 |
Queue capacity
Async submissions are checked against your queue capacity. A task or batch that would overflow it is rejected whole with
429 QUEUE_LIMIT_EXCEEDED, whose details carry queuedCount, batchSize, maxQueueSize and
remainingCapacity. Watch the queue with GET /v1/async/status and drop tasks that have not started with
DELETE /v1/async/queue (see managing the queue).
Headers
| Header | Sent on | Meaning |
|---|---|---|
X-RateLimit-Limit | Every response | Requests allowed per one-second window. |
X-RateLimit-Remaining | Every response | Requests left in the current window. |
X-Request-Id | Every response | The request's id (see request ids). |
X-Concurrent-Limit | Monitor responses | Concurrency slots on your plan. |
X-Concurrent-Current | Monitor responses | Slots in use. |
X-Concurrent-Remaining | Monitor responses | Slots free. |
X-Credits-Remaining | Monitor responses | Your credit balance. |
X-Credits-Charged | Monitor responses | Credits this request was charged. |
X-Latency-Ms | Monitor responses | Server-side processing time in milliseconds, excluding network transit. |
Reading limits in code
The SDKs retry 429s with jittered backoff on their own. To throttle before hitting a limit, read the headers from a response's metadata with the low-level
request method:
const { data, meta } = await client.request("POST", "/v1/monitor/chatgpt", { prompt: "Best CRM for small agencies", country: "US" });
console.log(meta.concurrentRemaining, meta.rateLimitRemaining, meta.creditsCharged);data, meta = client.request("POST", "/v1/monitor/chatgpt", {"prompt": "Best CRM for small agencies", "country": "US"})
print(meta.concurrent_remaining, meta.rate_limit_remaining, meta.credits_charged)