---
title: "Scan many sites · API docs · CheckAnySite"
description: "Scans as many as 10 sites at once."
url: "https://docs.checkanysite.com/api/batch-scans"
---

API reference

# Scan many sites

POST `/v1/scans/batch`

Scans as many as 10 sites at once.

Each site is handled as POST /scans would handle it (a recent result, a running scan or a new scan), in the order you sent them. A site refused by your credits, the daily limits or our rules gets an `error` in its place, and the other sites go ahead. Read each scan at its `links.self`.

Credits

Each site is charged as POST /scans charges it: its checks’ scan price for a new scan, or their stored price for a recent result or a running scan. Each scan’s credits are counted before the next site.

## Request

```bash cURL
curl -X POST "https://api.checkanysite.com/v1/scans/batch" \
  -H "Authorization: Bearer $CHECKANYSITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domains": ["example.com", "example.org"], "checks": ["ai"]}'
```

```python
from checkanysite import CheckAnySite

client = CheckAnySite()  # Reads the key from CHECKANYSITE_API_KEY.

batch = client.scans.batch(["example.com", "example.org"], checks=["ai"])
```

```javascript
const url = 'https://api.checkanysite.com/v1/scans/batch';
const response = await fetch(url, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHECKANYSITE_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    domains: ['example.com', 'example.org'],
    checks: ['ai'],
  }),
});
const batch = await response.json();
```

## Parameters

- `Idempotency-Key` string header

  A unique value for this request, such as a UUID. A retry with the same key within 24 hours returns the first response (`Idempotent-Replayed: true`), and never starts a second scan or charges twice. The same key with a different request returns `idempotency_key_reused`.

## Request body

JSON, with `Content-Type: application/json`. A field we don’t know is refused, so a typo never passes silently.

- `domains` array of string required body

  1 to 10 domains, or URLs whose host is used. A domain sent twice is answered once, in its first place.
- `checks` array of one of: ai, readiness, popularity, tech, dns, trust, summary, history body

  The checks to answer for each domain; left out, every check.
- `again` boolean body

  With the `readiness` check: ask it again, as on POST /scans.

  Default: `false`

## Response

| Status | Body | When |
| --- | --- | --- |
| 200 OK | `ScanBatch` | Every scan is complete, from recent results. |
| 202 Accepted | `ScanBatch` | Some scans are running. Read each at its `links.self`. |

```json Response 202: Scans on their way, and an address that isn’t a site
{
  "data": [
    {
      "id": "0b5a7a6e-1f7e-4d7c-9a4e-2f0d8b1c6a11",
      "domain": "wikipedia.org",
      "checks": [
        "ai"
      ],
      "status": "queued",
      "createdAt": "2026-11-10T09:30:00.000Z",
      "finishedAt": null,
      "complete": false,
      "failure": null,
      "result": null,
      "links": {
        "self": "https://api.checkanysite.com/v1/scans/0b5a7a6e-1f7e-4d7c-9a4e-2f0d8b1c6a11?checks=ai",
        "result": "https://checkanysite.com/site/wikipedia.org?focus=ai"
      }
    },
    {
      "input": "localhost",
      "domain": null,
      "error": {
        "code": "invalid_domain",
        "message": "That’s not a public website address."
      }
    }
  ]
}
```

- `data` array of value

  One item per domain: its scan (poll each `links.self`), or an `error`.

## Errors

| Status | Code | What happened |
| --- | --- | --- |
| 400 | [invalid\_json](https://docs.checkanysite.com/errors#invalid_json) | Invalid JSON |
| 400 | [invalid\_parameter](https://docs.checkanysite.com/errors#invalid_parameter) | Invalid parameter |
| 415 | [unsupported\_media\_type](https://docs.checkanysite.com/errors#unsupported_media_type) | Unsupported content type |
| 413 | [request\_too\_large](https://docs.checkanysite.com/errors#request_too_large) | Body too large |
| 401 | [missing\_api\_key](https://docs.checkanysite.com/errors#missing_api_key) | No API key |
| 401 | [invalid\_api\_key](https://docs.checkanysite.com/errors#invalid_api_key) | Unknown API key |
| 401 | [revoked\_api\_key](https://docs.checkanysite.com/errors#revoked_api_key) | Revoked API key |
| 401 | [expired\_api\_key](https://docs.checkanysite.com/errors#expired_api_key) | Expired API key |
| 429 | [rate\_limited](https://docs.checkanysite.com/errors#rate_limited) | Too many requests |
| 422 | [idempotency\_key\_reused](https://docs.checkanysite.com/errors#idempotency_key_reused) | Idempotency key reused |
| 409 | [idempotency\_key\_in\_use](https://docs.checkanysite.com/errors#idempotency_key_in_use) | Request in progress |
| 500 | [internal\_error](https://docs.checkanysite.com/errors#internal_error) | Internal error |
