API reference
Errors
HTTP status codes the API returns and how to handle each one.
Error shape
Errors use standard HTTP status codes. The body is a JSON object with a detail field, which is a string for every status except a 422 raised by request-body validation, where it is an array of field errors. Parse defensively: check the type before treating it as a message.
example
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{ "detail": "monthly quota exceeded" }422 on a rejected body
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{ "detail": [
{ "loc": ["body", "keyword"], "msg": "Field required", "type": "missing" }
] }Status codes
| Field | Type | Description |
|---|---|---|
| 200 | OK | Success. For a results fetch, the job is terminal and the parsed body is returned. |
| 202 | Accepted | A json/serpapi results fetch on a job that is still queued or running. Keep polling. |
| 400 | Bad Request | Invalid input on a query parameter, e.g. an output value other than html/json/serpapi. Detail is a string. |
| 401 | Unauthorized | Missing or invalid X-API-Key. |
| 403 | Forbidden | The requested locale is not enabled (staged rollout). Detail: "locale '{gl}' not enabled". |
| 404 | Not Found | No job exists with the given job_id. |
| 422 | Unprocessable | Two cases with different body shapes. A rejected request body fails schema validation and detail is an ARRAY of {loc, msg, type} objects. A results fetch whose stored HTML is unavailable returns detail as a string. |
| 429 | Too Many Requests | Monthly quota exhausted, the per-minute rate limit was exceeded, or the key is at its in-flight job ceiling (backpressure, not a quota — retry shortly). |
| 500 | Server Error | An unexpected server-side failure. Retry with backoff; if it persists, report it. |
Handling guidance
202— expected while polling. Wait 2 to 3 seconds and retry. Polls are billed no quota but they DO count against the per-minute rate limit (60 by default), so a tighter loop on a crawl that runs ~40s will 429 on its own polling.401 / 403— fix the key or wait for the locale to be enabled; retrying unchanged will not help.429— back off. If it is the rate limit, slow your request rate (including polls); if it is the in-flight ceiling, let submitted jobs settle before sending more; if it is the monthly quota, wait for the reset or raise the plan.500and transient network errors — retry with exponential backoff.
Distinguish partial from failed
A
partial job is not an error: it returns results, just fewer than the full 100. Check completeness (native output) to decide whether the coverage is acceptable before treating it as a failure.