Errors
Errors use standard HTTP status codes and always return the same JSON shape, so you can handle them in one place.
Error format
- { "error": "Missing or invalid API key." }
Status codes
| Status | Meaning |
|---|---|
200 | Success. |
400 | Bad request — a required parameter (e.g. url) is missing or malformed. |
401 | Missing or invalid API key. |
403 | URL blocked — a private, loopback or cloud-metadata address (SSRF protection). Also returned when a resource belongs to another key, such as a crawl job yours didn't create. |
404 | Unknown endpoint, or a crawl job that doesn't exist. |
422 | The page was fetched successfully but there wasn't enough content to analyse — currently only AI citability. |
429 | Burst rate limit or daily quota exceeded — see Rate limits. |
502 | The target URL couldn't be fetched or rendered (unreachable or upstream error). |
503 | The engine or an upstream service that endpoint depends on is unavailable, or is not configured on this server. |
A note on 503 and authentication order
Most endpoints check your API key first and return 401 before doing anything else. A few check that their engine or upstream service is available before authenticating, so an unauthenticated call to those can come back 503 rather than 401.
Keyword analysis goes further: it validates the keywords parameter before authenticating too, so a request with a missing or invalid key and no keywords returns 400, not 401. Don't use that endpoint to test whether a key is valid — send a valid keywords value, or test against /api/v1/audit instead.
Lighthouse, screenshot, waterfall and Core Web Vitals depend on Google upstream services, so treat 503 and 429 from those as expected states, not bugs.
Handling errors
Check the status code first, then read error for a human-readable message. 4xx errors are client-side (fix the request or key); 5xx and 429 are safe to retry with backoff.
Two endpoints report a negative result as a successful response rather than an error: uptime returns 200 with up: false for a site that's down, and Core Web Vitals returns 200 with hasFieldData: false when Chrome has too little traffic for the URL and its origin. Read the field, don't catch a status code.