---
title: "Errors · API docs · CheckAnySite"
description: "Every error has a stable code to branch on, a message that says what happened and what to do, and a request ID."
url: "https://docs.checkanysite.com/errors"
---

Concepts

# Errors

Every error has a stable code to branch on, a message that says what happened and what to do, and a request ID.

## The error object

When a request fails, the API returns an HTTP error status and a JSON body like the following:

```json Error body
{
  "error": {
    "code": "invalid_parameter",
    "message": "\"checks\" takes ai, readiness, popularity, tech, dns, trust, summary and history; \"whois\" isn't one of them.",
    "param": "checks",
    "docs": "https://docs.checkanysite.com/errors#invalid_parameter",
    "requestId": "req_8Hk2Qm9xT4bWzL0pRc7V"
  }
}
```

- `code` is stable. Branch on it in your code.
- `message` says what happened in plain language, and is safe to log.
- `param` names the parameter that caused the error, when there is one.
- `docs` links to the code’s entry on this page.
- `requestId` matches the `X-Request-Id` header. Include it when you contact us.

The MCP server returns the same codes inside a tool result, with `isError` set to `true`.

## Status codes

The following table lists every code and whether sending the same request again can succeed. [Rate limits](https://docs.checkanysite.com/rate-limits#retries) explains how long to wait. We may add codes within v1, so handle a code you don’t recognise by its status.

| Status | Code | Retry? |
| --- | --- | --- |
| 400 | invalid\_json | No |
| 400 | invalid\_parameter | No |
| 400 | invalid\_domain | No |
| 401 | missing\_api\_key | No |
| 401 | invalid\_api\_key | No |
| 401 | revoked\_api\_key | No |
| 401 | expired\_api\_key | No |
| 403 | read\_only\_key | No |
| 403 | browser\_request | No |
| 404 | not\_found | No |
| 404 | no\_result | No |
| 404 | scan\_not\_found | No |
| 405 | method\_not\_allowed | No |
| 409 | idempotency\_key\_in\_use | Yes, with backoff |
| 410 | scan\_expired | No |
| 413 | request\_too\_large | No |
| 415 | unsupported\_media\_type | No |
| 422 | site\_refused | No |
| 422 | idempotency\_key\_reused | No |
| 429 | rate\_limited | Yes, after Retry-After |
| 429 | quota\_exceeded | No |
| 429 | key\_limit\_reached | No |
| 429 | scan\_limit\_reached | No |
| 500 | internal\_error | Yes, with backoff |
| 503 | capacity | Yes, after Retry-After |

## Status 400

- invalid\_json Invalid JSON Retry: No

  The request body isn’t a valid JSON object.

  **What to do:** Send a JSON object, such as `{"domain": "example.com"}`, with `Content-Type: application/json`.
- invalid\_parameter Invalid parameter Retry: No

  A parameter is missing, unknown or has a value the API doesn’t accept. `param` names it.

  **What to do:** Check the parameter’s name, type and allowed values in the API reference.
- invalid\_domain Not a public domain Retry: No

  The address isn’t a public domain name we can check, such as an IP address, a private name or a typo.

  **What to do:** Send a domain, such as `example.com`. A full URL also works; we ignore its path.

## Status 401

- missing\_api\_key No API key Retry: No

  The request has no API key.

  **What to do:** Send your key in the Authorization header as `Bearer cas_live_…`, or in an `X-API-Key` header. Create a key at https://checkanysite.com/account/keys.
- invalid\_api\_key Unknown API key Retry: No

  The API key doesn’t exist, or it was copied incorrectly.

  **What to do:** Copy the key again from where you stored it. We show a key only once, so create a new one if you no longer have it.
- revoked\_api\_key Revoked API key Retry: No

  The API key was revoked and no longer works.

  **What to do:** Use another key, or create a new one at https://checkanysite.com/account/keys.
- expired\_api\_key Expired API key Retry: No

  The API key has expired: it reached the expiry date set when it was created, or the end of its grace period after a rotation.

  **What to do:** Use the key that replaced it, or create a new one at https://checkanysite.com/account/keys. To avoid downtime, rotate keys before they expire.

## Status 403

- read\_only\_key Read-only key Retry: No

  This key is read-only. It can read stored results but can’t start a scan.

  **What to do:** Get the stored result with GET /v1/sites/{domain}, or use a key with full access to start scans.
- browser\_request Request from a browser Retry: No

  The API accepts requests from servers only, because a key sent from a browser is visible to anyone who opens the page.

  **What to do:** Call the API from your server or a serverless function, and keep the key there.

## Status 404

- not\_found Endpoint not found Retry: No

  There is no API endpoint at this path.

  **What to do:** Check the path in the API reference. Every endpoint is under the base URL, such as /v1/sites/{domain}.
- no\_result No stored result Retry: No

  We have no stored result for this site with these checks, or none as recent as you asked for.

  **What to do:** Scan the site with POST /v1/scans. This request cost nothing.
- scan\_not\_found Scan not found Retry: No

  There is no scan with this ID.

  **What to do:** Use the `id` returned when you started the scan.

## Status 405

- method\_not\_allowed Method not allowed Retry: No

  The endpoint exists but doesn’t accept this HTTP method. The `Allow` header lists the methods it accepts.

  **What to do:** Use one of the methods in the `Allow` header.

## Status 409

- idempotency\_key\_in\_use Request in progress Retry: Yes, with backoff

  A request with this `Idempotency-Key` is still being processed.

  **What to do:** Retry in a second with the same key. You’ll get the first request’s response, without a second charge.

## Status 410

- scan\_expired Scan expired Retry: No

  This scan is older than the results we keep, so its result is no longer available. We keep each site’s latest result.

  **What to do:** Get the site’s latest result with GET /v1/sites/{domain}, or scan it again with POST /v1/scans.

## Status 413

- request\_too\_large Body too large Retry: No

  The request body is larger than the API accepts.

  **What to do:** Send only the documented fields.

## Status 415

- unsupported\_media\_type Unsupported content type Retry: No

  The request body has a content type other than JSON.

  **What to do:** Send the body as JSON, with `Content-Type: application/json`.

## Status 422

- site\_refused Site not checked Retry: No

  We don’t check this kind of site, such as adult websites.

  **What to do:** There’s nothing to do. This request cost nothing.
- idempotency\_key\_reused Idempotency key reused Retry: No

  This `Idempotency-Key` was sent with a different request in the last 24 hours. Each key belongs to one request.

  **What to do:** Send a new key, such as a new UUID, with each new request. Reuse a key only to retry the same request.

## Status 429

- rate\_limited Too many requests Retry: Yes, after Retry-After

  This key has made more requests than its rate limit allows.

  **What to do:** Wait the number of seconds in the `Retry-After` header, then retry. Spread your requests out over time.
- quota\_exceeded Monthly credits used up Retry: No

  The account has used all its credits for this month.

  **What to do:** Wait for the reset on the first of the month (UTC), or ask for more credits at https://checkanysite.com/account/usage#more-credits; extra credits are free during launch. Stored results cost the fewest credits.
- key\_limit\_reached Key limit reached Retry: No

  This key has used the monthly credit limit set for it.

  **What to do:** Raise the key’s limit at https://checkanysite.com/account/keys, use another key, or wait for the reset on the first of the month (UTC).
- scan\_limit\_reached Daily scan limit reached Retry: No

  The account has started its 25 new scans for today (UTC).

  **What to do:** Get stored results with GET /v1/sites/{domain}, or start the scan after 00:00 UTC. This request cost nothing.

## Status 500

- internal\_error Internal error Retry: Yes, with backoff

  Something went wrong on our side. This request cost nothing.

  **What to do:** Retry in a minute. If the error continues, contact us and include the `requestId`.

## Status 503

- capacity No scan capacity Retry: Yes, after Retry-After

  The API can’t start new scans right now. Stored results still work.

  **What to do:** Get stored results with GET /v1/sites/{domain}, or start the scan later; the message says when.
