query_too_complex
400 invalid_request. The query is over a budget, and the message says which, what it measured and the limit.
| HTTP status | type | Surfaces |
|---|---|---|
| 400 | invalid_request | REST, GraphQL |
What it means
The query is over a budget, and the message says which, what it measured and the limit. The budgets: 5,000 entries (each totalCount and each filter or sort through a relation costs 500 more), 10 root fields, 25 lists, 1,000 fields, depth 8, 32 KB documents, entries 5 levels deep (4 relations below the root), 12 relations expanded per root field, 200 values per list operator, 50 filter conditions nested at most 8 deep.
| When | What the hint tells you |
|---|---|
| past 5 levels of entries, 12 expansions or 5,000 nodes | for depth, the 5 levels and to read the deeper entries with a second request; for nodes, the list to change and a limit: that fits; otherwise the three caps, and to lower a limit: or expand fewer relations |
What to do
Ask for fewer fields, a smaller first, or fewer nested relations; split one query into several.
The response
HTTP 400:
{
"error": {
"type": "invalid_request",
"code": "query_too_complex",
"message": "This request could return 5,025 entries, over the limit of 5,000.",
"docs": "https://docs.capacms.com/errors/query_too_complex"
},
"meta": {
"version": "2026-10-01",
"contract": 1,
"requestId": "req_0f3c…"
}
}On GraphQL
/api/graphql answers the same code inside errors[].extensions. The status depends on the Accept header you send (status codes):
application/json | graphql-response+json | When |
|---|---|---|
| 200 | 400, or 200 on a field | any limit above; after SQL, more than 5,000 rows read |
See also
invalid_parameter
400 invalid_request. A request parameter is missing or out of range: first outside 1 to 200, more than 3 sort values, a non-UUID id, bad JSON in variables.
count_unavailable
400 invalid_request. totalCount could not be computed cheaply for this filter (a relation filter matching over 50,000 entries).