Esc

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

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-Keystringheader

    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.

  • domainsarray of stringrequiredbody

    1 to 10 domains, or URLs whose host is used. A domain sent twice is answered once, in its first place.

  • checksarray of one of: ai, readiness, popularity, tech, dns, trust, summary, historybody

    The checks to answer for each domain; left out, every check.

  • againbooleanbody

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

    Default: false

Response

StatusBodyWhen
200 OKScanBatchEvery scan is complete, from recent results.
202 AcceptedScanBatchSome scans are running. Read each at its links.self.
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."
      }
    }
  ]
}
  • dataarray of value

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

Errors

StatusCodeWhat happened
400invalid_jsonInvalid JSON
400invalid_parameterInvalid parameter
415unsupported_media_typeUnsupported content type
413request_too_largeBody too large
401missing_api_keyNo API key
401invalid_api_keyUnknown API key
401revoked_api_keyRevoked API key
401expired_api_keyExpired API key
429rate_limitedToo many requests
422idempotency_key_reusedIdempotency key reused
409idempotency_key_in_useRequest in progress
500internal_errorInternal error