Skip to content

Limits and requests

The request rate, page sizes and upload sizes the server enforces, and how to send query values.

Rate limit

Each task API key has its own budget: 7,500 requests per minute by default, counted in fixed one-minute windows across the HTTP API and the CLI together. A key that an agent uses to act as itself, rather than as a person, has a smaller budget, 2,500 requests per minute by default. Your deployment’s administrator sets these numbers and decides whether going over the limit is refused or only recorded.

Over budget, the server answers 429 Too Many Requests with a Retry-After header in whole seconds (at least 1):

HTTP/1.1 429 Too Many Requests
Retry-After: 12
Content-Type: application/json
{ "ok": false, "error": "rate_limited", "scope": "principal", "retryAfterMs": 11350 }

scope: "principal" means your key used up its own budget. Wait at least Retry-After seconds, then retry, and spread scheduled jobs out instead of starting them on the same second.

Sizes

LimitValue
Page size (limit, pageSize)1 to 100; a run’s task results 1 to 50. Defaults differ by endpoint.
totalCountOn GET /traces/sessions and GET /traces/calls, counts up to 10,000, then reports totalCountIsCapped: true.
Trace search and filtersUp to 500 characters, and up to 20 filter conditions.
Trace time window90 days unless your administrator sets another maximum. A longer window is shortened; on GET /traces/sessions, the response’s window object says so.
A file for a task (evals file upload)100 MiB. The CLI refuses a larger file before sending anything, with exit code 2.
A CLI request that changes data10 MiB. The server refuses a larger one, such as a large dataset import, with 413, and the CLI exits 1.

Query values

Every endpoint is under https://<your-deployment>/api/v1/evals. Single values are plain query parameters. The server reads true and false as booleans, numbers as numbers, a repeated key as a list, and a value that starts with { or [ as JSON. A key sent once stays one value; send lists as JSON. A text value that looks like a number (404, -1, 1.5), or is true or false, is read as a number or a boolean and refused with 400. Send objects and lists, such as trace filters, a workspace scope or workflowIds, as JSON in one query value, and let your HTTP library URL-encode them. Unknown parameters are ignored without an error, so a typo such as workspace= gets the default scope. Inside a filter, value is always a string.

Terminal window
curl -sS --fail-with-body --get "$CONTEXT_APP_ORIGIN/api/v1/evals/traces/sessions" \
-H "Authorization: Bearer $CONTEXT_API_KEY" \
--data-urlencode 'from=2026-10-01T00:00:00Z' \
--data-urlencode 'to=2026-10-31T00:00:00Z' \
--data-urlencode 'filters=[{"field":"success","operator":"equals","value":"false"}]' \
--data-urlencode 'pageSize=25'

Paging

Lists that can grow large are paged. With cursor paging, pass the previous response’s nextCursor back as cursor (GET /analytics/records returns it as pageInfo.nextCursor); a null nextCursor means the last page. GET /traces/sessions, GET /traces/sessions/{sessionId}, GET /runs/{runId}/tasks and GET /analytics/records page this way. GET /feedback and GET /traces/calls use page numbers: pass page, starting at 1. Over HTTP, smaller lists such as datasets and evaluations return everything in one response; the CLI’s list commands page them with --cursor and --limit.

Responses are JSON. Times are ISO 8601 strings in UTC, IDs are strings and costs are numbers in U.S. dollars. Ignore fields you don’t know, because new fields can be added.