When a request fails, the status code says what kind of problem it is, and the body says what exactly, in words you can show a person. Many errors also carry a code for your program to match on.
JSON
{ "error": "Domain not verified. Add \"staging.example.com\" to your verified domains before scanning.", "code": "DOMAIN_NOT_VERIFIED", "scanHost": "staging.example.com", "dcProvider": null }Match on code when there is one; the error text can be reworded. The credit errors (402) are the exception to the shape: error is an object with its own code and message.
JSON
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "This End-to-End scan reserves 2 credits. You have 0 available.",
"hold": 2,
"available": 0,
"typical": { "min": 1, "max": 1 },
"actionLink": { "label": "Buy credits", "href": "/org/org_8f2…/billing/credits" }
}
}Status codes
| Status | Means |
|---|---|
200, 201 | It worked. 201 only for a new domain. |
400 | Something in the request is wrong: a missing field, a bad value, a malformed Idempotency-Key. Fix it before retrying. |
401 | No key, an unknown key, or an expired one. |
402 | Credits: not enough, the card on file was declined, or the key's monthly limit. |
403 | The key can't do this: its scope, its plan, a team boundary, or an unverified domain. |
404 | Not found, or not yours. The API doesn't say which. |
409 | A conflict: the scan already finished, or an Idempotency-Key used for a different request or still starting its scan. |
413 | The account's storage is full. |
422 | The site is behind protection the scanner can't get through yet. |
429 | Too many requests, or another scan is running in the workspace. Wait for Retry-After seconds. |
500, 503 | Our side. Retry with backoff; a POST /scans retried with the same Idempotency-Key can't start a second scan. |
Codes
code | Status | When |
|---|---|---|
INVALID_SCAN_TYPE | 400 | type isn't e2e or security. |
IDEMPOTENCY_KEY_INVALID | 400 | The Idempotency-Key isn't 1 to 255 printable characters without spaces. |
INVALID_URL | 400 | The scan's address can't be read. |
AUTH_REQUIRED | 401 | No signed-in person behind the request. |
INSUFFICIENT_CREDITS | 402 | The workspace doesn't have what the scan reserves. Inside error. |
CARD_FAILED | 402 | Auto-refill couldn't charge the card. Inside error. |
KEY_CREDIT_LIMIT | 402 | The key's monthly credit limit is used up, or this scan would go over it. Has limit, used, hold. |
DOMAIN_NOT_VERIFIED | 403 | The site's domain isn't verified (for a team key, by anyone on the team). Has scanHost. |
IDEMPOTENCY_KEY_REUSED | 409 | This Idempotency-Key started a different request. |
IDEMPOTENCY_IN_PROGRESS | 409 | A request with this Idempotency-Key is still starting its scan. Retry-After: 2. |
SITE_PROTECTED | 422 | The site is behind basic auth, Vercel Deployment Protection, Cloudflare Access or Netlify password protection. Has protection and host. |
RATE_LIMITED | 429 | Too many requests with this key. Has retryAfter. |
ORG_IN_FLIGHT_CAP | 429 | Another scan is running in the workspace. Has runningScanId when known, and Retry-After: 30. |
SCAN_QUEUE_UNAVAILABLE | 503 | Scans can't be queued right now. Retry later. |
The CLI turns these into its own codes with a fix for each: see CLI troubleshooting.