Skip to content

Errors

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.

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.

{
"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" }
]
}