Skip to main content

Rate limits and errors

Available onProResearch

The API limits how many requests a key and an account can make, and answers every refusal with a status code and a stable error code. Read the code, not the message text: the code does not change.

Limits​

Two limits apply to every call that uses a key:

  • Per key, per hour. Each key has its own hourly limit, capped at the maximum of your plan.
  • Per account, per day. All your REST calls share one daily budget. The day is UTC and resets at 00:00 UTC.

The numbers for each plan are in the table on Keys, scopes and limits. A few routes have a short extra limit per minute: asking a question (POST /ask) and starting or finishing an upload allow a limited number of calls a minute.

Headers​

Every answer to a call that passed the hourly check carries:

  • X-RateLimit-Limit: the limit in force for this key.
  • X-RateLimit-Remaining: calls left in the current hour.

When you are over a limit the answer is 429 with Retry-After, the number of seconds to wait.

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
Retry-After: 1260

Retry politely​

Wait for Retry-After seconds and try again. Do not retry at once in a loop. A script that makes many calls should stop when the daily limit is reached and continue the next day. The example in Examples shows a request function that does this.

GET /rest/v2/usage tells you how much of the day you have used.

The error shape​

Every refusal uses one JSON shape. success is false, and error holds the details.

{
"success": false,
"error": {
"statusCode": 403,
"message": "This API key lacks the scope read:library.",
"code": "SCOPE_REQUIRED",
"details": { "scopes": ["read:library"] },
"timestamp": "2026-11-04T09:00:00.000Z",
"path": "/rest/v2/search",
"method": "GET"
}
}

code is the machine-readable part. It can be missing on plain validation or not-found answers, where statusCode and message carry the meaning. message may be a list of strings when several fields are wrong.

Status and error codes​

StatusCodeMeaning
400-The request is malformed. A query parameter or body field the route does not know is also a 400.
400SCOPE_NOT_ALLOWEDYou asked for a scope your plan does not include when creating a key.
401API_KEY_INVALIDThe key is missing, unknown, revoked, expired or blocked. The answer carries WWW-Authenticate: Bearer realm="readsira".
401API_KEY_IN_QUERYThe key was sent in the address. Send it in a header.
402PLAN_REQUIREDThe plan has no REST API (Free), or no uploads. MCP keys still work at /mcp.
402PLAN_LIMIT_REACHEDA count limit is reached, for example the answers per month.
402AI_QUOTA_EXCEEDEDThis month's AI budget is used up (POST /ask).
402PROJECT_LIMIT_REACHEDA project is at your plan's limit of items.
403SCOPE_REQUIREDThe key lacks the scope the route needs. error.details.scopes names it.
404-Not found, or not yours. The API does not say which.
409PROJECT_ARCHIVEDYou tried to write to an archived project.
429RATE_LIMITEDThe hourly or daily limit. error.details has window (hour or day), limit and retryAfterSeconds.
503AI_PAUSEDAI is paused for the day (POST /ask only). Search keeps working.

A 429 without a code comes from the short per-minute limit on a route. Wait and retry in the same way.

Limits of the inputs​

The API checks every input and refuses the whole request with 400 when one is out of range.

RouteInputAllowed
GET /searchq1 to 500 characters
GET /searchlimit1 to 20, default 8
POST /askquestion1 to 2000 characters
POST /askbookmarkIds1 to 50 ids
GET /documents/:idoffset0 or more characters
GET /documents/:idmaxChars1 to 20,000, default 12,000
GET /documents/:id/chunkslimit1 to 100, default 20
GET /documents/:id/transcriptlimit1 to 500
GET /projectslimit1 to 50, default 20
GET /projects/:id/contextq1 to 500 characters
GET /projects/:id/contextmaxChars1 to 32,000, default 16,000

Each route has a full list with types in the REST API v2 reference.