Errors

One error format everywhere, with stable codes you can program against.

Errors use RFC 9457 problem details, with Content-Type: application/problem+json:

{
  "type": "urn:typesearch:error:invalid_request",
  "title": "Bad request",
  "status": 400,
  "detail": "max_results: Too big: expected number to be <=50",
  "code": "invalid_request",
  "request_id": "req_8fKq2mZr1xYt",
  "errors": [{ "path": "max_results", "message": "Too big: expected number to be <=50" }]
}

Use code in your code — it is stable. title, detail and message are for people and can change. title and detail come in English; send Accept-Language: es to get them in Spanish. Every response, successful or not, carries an X-Request-Id header: include it when you contact support.

Codes

StatuscodeWhat to do
400invalid_json, invalid_requestFix the request. errors lists each invalid field. Unknown fields are rejected too.
400invalid_url, invalid_site, site_not_found, unsupportedFix the URL or site.
401missing_api_key, invalid_api_key, revoked_api_keySee Authentication.
402budget_too_smallRaise max_tokens.
402insufficient_creditsNo credit left on your account. Top up in the dashboard.
402spend_limit_reachedThe key reached its monthly spend limit. Raise it in the dashboard.
403robots_disallowedThe site’s robots.txt disallows it, or it couldn’t be read (we retry after 10 minutes).
403source_unavailableThe source isn’t available right now. We don’t say why, and it may be temporary. Try another source.
404job_not_foundThe job does not exist for this key, or it expired (jobs last a day).
404chart_not_foundNo chart with that id for your organization: it was deleted or it expired. See Charts.
422insufficient_dataA chart from a query found no articles about the topic in the period (with index or questions: not enough data for the chart). Not billed. Try more days or a broader query.
429rate_limitedRetry after Retry-After seconds.
429quota_exceededDaily token quota used. It resets at 00:00 UTC.
499cancelledThe search stopped because the client closed the connection or aborted the stream. Nothing to fix; send it again if you still need it.
500internal_errorSomething failed on our side. Retry; if it keeps happening, contact support with the request_id.
502site_unreachable, invalid_redirect, bot_protectionThe site failed. Try again later or another site.
503upstream_unavailable, browser_unavailable, browser_busyTemporary. Retry with backoff; browser_busy says when in Retry-After.
503shutting_downThe server is restarting. Retry after Retry-After seconds.
503spend_cap_reachedThe service reached its daily spend cap. Retry-After says when it resets (00:00 UTC).
503job_interruptedIn a job’s error (GET /v1/jobs/{id}): the server restarted before the job finished. Request it again.
504timeout, site_timeoutTemporary. Retry, or use a lighter mode.

In POST /v1/contents each URL has its own status: a page from a source that isn’t available comes back with source_unavailable in results[].error.code, and the rest of the request succeeds.

Retries

The SDKs retry connection errors, timeouts, 429 rate_limited and 5xx twice, with exponential backoff and jitter, honouring Retry-After. They never retry quota_exceeded. Calling the API directly, do the same.

Warnings are not errors

Things that don’t stop a request — a domain that is not in the index, a budget reached — come back in the response’s warnings array, each with a code and a message (in English, or in Spanish with Accept-Language: es).

On this page