# Errors

Errors have one shape:

```json
{"error": {"code": "validation_failed", "message": "Some fields are not valid.",
           "details": {"fields": {"domain": ["Site with this Domain already exists."]}}}}
```

| HTTP | code | When |
|---|---|---|
| 400 | `bad_request` | The request is malformed (bad JSON, unknown parameter value). |
| 401 | `unauthorized` | No key, a malformed key, an unknown key, a revoked key or an expired key. |
| 402 | `payment_required` | The plan has expired, or the feature needs an add-on the account does not have. |
| 403 | `forbidden` | The key lacks the scope, is restricted to other sites, the IP is not on its allowlist, or the account / site is suspended. |
| 403 | `ip_not_allowed` | The request came from an IP address that is not on the key's allowlist. |
| 403 | `scope_missing` | The key does not have the scope this endpoint needs (see details.required). |
| 403 | `site_not_allowed` | The key is restricted to other sites. |
| 404 | `not_found` | The object does not exist or does not belong to this account. |
| 409 | `conflict` | The site is busy (another job is running) or not in a state that allows the action. |
| 413 | `too_large` | An upload or a file read is larger than the limit. |
| 422 | `validation_failed` | Some fields are invalid; details.fields lists the message(s) for each field. |
| 429 | `rate_limited` | Too many requests for this key; see Retry-After. |
| 500 | `internal_error` | Something failed on our side. It is logged; the request_id helps support find it. |
| 503 | `api_disabled` | The API is switched off for maintenance. |
| 503 | `unavailable` | A server this call depends on did not answer; try again in a few minutes. |

Every answer has an `X-Request-Id` header. If you contact support about a failed call, quote it.
Validation messages are the same messages the panel shows for the same form.
