Rate limits and quotas

Agent access is metered per token and per workspace, in fixed UTC windows. Limits depend on your plan.

On this page

Quotas by plan

LimitTeamBusiness
Requests per UTC minute, per token60120
Requests per UTC day, per token5,00020,000
Requests per UTC day, per workspace (all tokens together)15,00060,000
List page size (default and maximum)5050
Row budget per report query call1,0005,000

The Growth plan does not include agent access. To compare plans, see pricing.

How the windows work

Windows are fixed, not sliding. The minute window resets at the start of each UTC minute, and the day windows reset at 00:00 UTC. A request must fit within all three limits: the token's minute, the token's day and the workspace's day.

Counting is shared. If you run several agents or processes on the same token at once, they draw on the same counters.

What counts

Each authorized operation call counts as one request:

  • each REST request to an operation;
  • each MCP tools/call;
  • each page of a list. Fetching three pages costs three requests.

These don't count:

  • MCP initialize and tools/list;
  • the discovery documents, /api/v1/openapi.json and /llms.txt;
  • requests rejected before they are authorized, such as a bad token (401), agent access being off (403 not_enabled), invalid arguments (404) or a missing scope (403 forbidden).

The 429 response

When a request goes over a quota, REST returns 429:

http
HTTP/1.1 429 Too Many Requests
retry-after: 12
content-type: application/json; charset=utf-8
cache-control: no-store
x-request-id: …

{
  "error": {
    "code": "rate_limited",
    "message": "The rate limit for this credential was exceeded. Retry later."
  },
  "request_id": "…",
  "retry_after_seconds": 12
}

Retry-After and retry_after_seconds carry the same whole number of seconds, always at least 1. Over MCP the same body arrives as a tool result with isError: true at HTTP 200. See Errors over MCP.

The API does not send X-RateLimit-* or RateLimit-* headers, and it doesn't report how many requests remain. Use Retry-After as your signal.

Backing off

  • On a 429, wait at least retry_after_seconds before the next call on that token. Retrying sooner usually fails again.
  • If you run several workers on one token, pause all of them, since they share the counters.
  • A long wait usually means a daily quota is spent. Resume after 00:00 UTC rather than polling.
  • For 500 internal_error, retry with exponential backoff and jitter, and cap the number of attempts.
  • Page through large lists steadily instead of in bursts. At 50 items a page, 60 requests a minute is up to 3,000 items a minute on one token.

Rows per report query

Report queries (run_semantic_query and run_saved_query) return aggregate rows. Two limits apply to each call:

  • The query's own limit: from 1 to 1,000, with a default of 100.
  • Your plan's row budget per call: 1,000 on Team and 5,000 on Business.

A call returns at most the smaller of the two. Every plan's row budget is at least 1,000, so in practice a query returns up to its own limit, and never more than 1,000 rows.

Results are never cut silently. When more rows exist than the call returned, the result has truncated: true and truncatedBy says which limit applied. With today's limits that is "query_limit":

  • If limit is below 1,000, raise it and run the query again.
  • If you are already at 1,000, split the question into narrower queries, for example one per quarter, or add filters or drop a dimension. Each query counts as one request.

truncatedBy can also be "row_budget", meaning your plan's row budget ended the result. Handle it the same way.

Details of the query shape are on the Reports page.

Next steps

Was this page helpful?

Need help? Contact support