Errors
The envelope
Section titled “The envelope”Every error response, whichever route and whichever status, is a JSON object with the same three keys:
{ "error": "unsupported_geo", "message": "geo must be a supported ISO 3166-1 alpha-2 country code; see details for the full list", "request_id": "5ffaa523-2163-4e7f-8d46-bcc47d292de8", "details": ["us", "in", "gb", "ca", "au", "de", "fr", "sg", "ae", "jp", "ad", "af"]}details is truncated above. The real response lists all 193 supported codes,
in the order on Targets & geo.
| Key | Meaning |
|---|---|
error |
A stable, machine-readable code from the table below. |
message |
Human-readable and safe to show an end user. |
request_id |
The same value as the X-Request-Id response header. Quote it in a support request. |
details |
On unsupported_geo only: every supported country code, all 193 of them. |
issues |
On invalid_request from a validator: one { field, message } per failed field. field is the dotted path, empty for the whole input. |
X-Request-Id is sent on every response, success or failure. Send a UUID as
X-Request-Id on the request to have it echoed; anything else is replaced.
| Code | Status | When | Charged |
|---|---|---|---|
invalid_request |
400 | A parameter or body field failed validation. issues lists each field. |
No |
unsupported_geo |
400 | geo is not one of the 193 supported countries. details lists them all. |
No |
unsupported_parameter |
400 | The target cannot serve page, num or safe as sent, such as page above 1 on bing_search. Targets & geo lists every rule. |
No |
unauthorized |
401 | No accepted credential. Also what a session-only route answers to a bearer key. | No |
not_found |
404 | An unknown route, or an API key id that is not on this account. | No |
quota_exceeded |
402 | The account has nothing left to spend: a trial with its 100 free requests gone, or a paid plan with both its quota and its credit balance at zero. | No |
rate_limited |
429 | The credential’s per-minute limit is spent. Wait Retry-After seconds. |
No |
internal_error |
500 | A fault on our side. The detail is in our logs under request_id. |
No |
upstream_error |
502 | The search provider could not be reached or answered an unusable payload. | Yes |
upstream_timeout |
504 | The search provider did not answer within the 25-second budget. | Yes |
The two upstream codes are charged because the search was run and only the answer is missing.
quota_exceeded is the one code that carries more than the three envelope
keys: it adds plan, quota, credits_used, remaining and resets_at, so
a client can show what is left and what to do next. resets_at is null on
the trial, whose allowance never resets. Pricing and
quotas has the full response.
Errors inside a bulk response
Section titled “Errors inside a bulk response”POST /v1/bulk answers 200 whenever the body itself was accepted, even when
every row failed. A failed row is an object with status: "error", an
error code and a message, and no request_id of its own; the batch’s is
in the X-Request-Id header. A row can carry invalid_request,
unsupported_geo, unsupported_parameter (not charged), upstream_error,
upstream_timeout (charged) or internal_error (not charged). Rows still
running when the 60-second batch budget expires are answered
upstream_timeout.
A 400 invalid_request on the bulk request as a whole (for instance
queries with more than 50 entries) means nothing ran and nothing is charged.
A validation example
Section titled “A validation example”{ "error": "invalid_request", "message": "Too big: expected number to be <=20", "request_id": "d8bf5452-3615-438b-899c-d77bf0948b34", "issues": [ { "field": "num", "message": "Too big: expected number to be <=20" } ]}