Search
Errors and rate limits
Errors use standard HTTP status codes and a JSON body with a detail field. A refused search is never charged.
Error body
{
"detail": "wallet balance (120 credits) is below the estimated cost of this search (~2400 credits, EUR 2.40) and no free queries remain"
}
A request that fails validation (422) has a list instead, one entry per problem:
{
"detail": [
{ "type": "less_than_equal", "loc": ["body", "top_k"],
"msg": "Input should be less than or equal to 50", "input": 80 }
]
}
Match on the status code, not on the wording of detail: the text is for people and may change.
Status codes
| Status | When | What to do |
|---|---|---|
400 | The Idempotency-Key is longer than 255 characters. | Use a shorter key, such as a UUID. |
401 | No bearer token, or the key or token is unknown, revoked or expired. | Check the Authorization header; create a new key if it was revoked. |
402 | No free searches left and the wallet holds less than the search's estimated cost. | Top up, or lower top_k. Do not retry unchanged. |
403 | The key's scopes do not cover this index or use case, the action is reserved for TRIVDA operators, or the organisation is suspended. | Use a key with the right scopes. A suspension is lifted by TRIVDA. |
404 | The resource does not exist or is not yours, for example another organisation's query_id or dataset. | Check the id. |
409 | A request with the same Idempotency-Key is still running, or a dataset id is already owned by another organisation. | Retry the search after a moment; choose another dataset id. |
422 | The body is invalid (for example a blank query or top_k above 50), or an Idempotency-Key was reused with a different body. | Fix the request; use a new key for a new search. |
429 | A rate limit or quota was exceeded. | Wait the number of seconds in Retry-After, then retry. |
500, 502, 503 | Something failed on TRIVDA's side. | Retry with backoff and the same Idempotency-Key, so a search that did run is not charged twice. |
Rate limits
Limits apply per organisation, across all its keys, to searches, re-fetches and uploads. They are counted in three windows, checked in this order:
| Window | Default limit | Resets |
|---|---|---|
| Per minute | 60 requests | At the start of each minute |
| Per day | 10,000 requests | At midnight UTC |
| Per month | 200,000 requests | On the first of the month, UTC |
- The first limit crossed answers
429withRetry-After: the seconds until that window resets. - Your organisation's own limits and what is left:
GET /api/v1/search/quota. Higher limits are set per organisation on request. - A request refused by a limit is not charged.
{
"rpm_limit": 60, "rpm_remaining": 58,
"daily_quota": 10000, "daily_remaining": 9811,
"monthly_quota": 200000, "monthly_remaining": 196402,
"free_queries_remaining": 0,
"wallet_balance_tokens": 47790
}
wallet_balance_tokens is the wallet in credits; the name is historical.
Retrying safely
- Send an
Idempotency-Keywith every search, and reuse it on every retry of that search. - Retry
429afterRetry-After, and5xxor network errors with exponential backoff (for example 1, 2, 4, 8 seconds, then give up). - Do not retry
400,401,402,403,404or422unchanged: they will fail the same way.