Docs·API reference
Rate limits
Two limits per account, requests per minute and input tokens per UTC day, and headers on every response that tell you where you stand.
The limits #
The Preview plan is free and has these limits per account. All your keys and the playground share them. Access is by invitation during the preview: request access.
| Limit | Value | How it works |
|---|---|---|
| Requests per minute | 60 | Counted over the last 60 seconds. Calls to /v1/answers, /v1/extract and /v1/convert count, and so do questions and uploads in the playground. |
| Input tokens per UTC day | 2,000,000 | Resets at 00:00 UTC. A request that would go over is refused before the document is read. |
| Active API keys | 5 | Revoke a key to create another. |
Each request also has size limits:
| Per request | Limit |
|---|---|
| Document | 1,000,000 characters |
| Question | 300 characters |
Fields per /v1/extract call |
20 |
File to /v1/convert |
10 MB |
The headers #
Every API response carries these headers:
| Header | Meaning |
|---|---|
x-ratelimit-limit-requests |
Requests allowed per minute. |
x-ratelimit-remaining-requests |
Requests left in the current minute. |
x-ratelimit-reset-requests |
Seconds until a request slot frees up. |
x-ratelimit-limit-tokens |
Input tokens allowed per UTC day. |
x-ratelimit-remaining-tokens |
Input tokens left today. |
x-ratelimit-reset-tokens |
Seconds until the daily budget resets at 00:00 UTC. |
x-request-id |
The id of this request, req_…. |
A 429 or 503 response also carries retry-after, in seconds.
HTTP
HTTP/1.1 200 OK
content-type: application/json
x-request-id: req_8fK2mQ1wZt
x-ratelimit-limit-requests: 60
x-ratelimit-remaining-requests: 59
x-ratelimit-reset-requests: 60
x-ratelimit-limit-tokens: 2000000
x-ratelimit-remaining-tokens: 1948766
x-ratelimit-reset-tokens: 31440When you hit a limit #
You get a 429 with one of two codes:
JSON
{"error": {"type": "rate_limit_error", "code": "requests_per_minute",
"message": "more than 60 requests in a minute; retry in 12 s"}}requests_per_minute: waitretry-afterseconds, then send again.tokens_per_day: today's input tokens would be exceeded.retry-afteris the time until 00:00 UTC. The refused request used no tokens.
A 503 with queue_full or queue_timeout means we are busy, not that you used too much. Wait retry-after seconds and retry.
Stay under the limits #
- Read the headers. Slow down when
x-ratelimit-remaining-requestsgets close to 0. - Batch fields. One
/v1/extractcall with ten fields is one request, not ten. It still uses ten reads of tokens. - Send less text. Every question reads the whole document. Sending the right section instead of the whole file saves tokens. See long documents.
- Let the SDK retry. The Python and JavaScript SDKs retry 429 and 503 with backoff and honour
retry-after.
Reading the headers in code:
curl
curl -s -D - -o /dev/null https://platform.xerj.ai/v1/models \
-H "Authorization: Bearer $XERJ_API_KEY" | grep -i x-ratelimitPython
from xerj import XERJ, RateLimitError
client = XERJ()
try:
res = client.answers.create(document=doc, question="What is the notice period?")
except RateLimitError as err:
print(err.code, err.headers.get("retry-after"), err.request_id)JavaScript
import XERJ, { RateLimitError } from "xerj";
const client = new XERJ({ apiKey: process.env.XERJ_API_KEY });
try {
const res = await client.answers.create({ document: doc, question: "What is the notice period?" });
} catch (err) {
if (err instanceof RateLimitError) console.log(err.code, err.headers.get("retry-after"), err.request_id);
else throw err;
}Need higher limits? The Preview plan is the only plan during the preview.