---
title: "Batch resolve: POST {domains:[..]} (1-100) and receive each domain's signed ResolveV1 answer in one response"
method: POST
path: "/api/v1/resolve"
tags: ["Core"]
---

# Batch resolve: POST {domains:\[..\]} (1-100) and receive each domain's signed ResolveV1 answer in one response

`POST /api/v1/resolve`

## Request

- Base URL: `https://crawlcheck.io`
- URL: `https://crawlcheck.io/api/v1/resolve`
- Auth: none required

## Request body

- object
  - `domains` string[], required

## Response `200`

crawlcheck-resolve-batch

- ResolveBatchV1
  - `kind` 'crawlcheck-resolve-batch', required
  - `v` unknown, required
  - `count` integer, required
  - `ms` integer
  - `reading` string
  - `answers` object[], required
    - `domain` string, required
    - `status` integer, required: the HTTP status this domain's own lookup would have returned
    - `served` string
    - `answer` ResolveV1: GET /api/v1/resolve?domain=: what an agent should know before acting on a domain. Signed with Ed25519 over sha256 of the canonical JSON of every field except sha256 and signature, message prefix crawlcheck-data-v1\n; verify offline with crawlcheck-verify.mjs.
      - `kind` 'crawlcheck-resolve', required
      - `v` unknown, required
      - `schema` string
      - `domain` string, required
      - `answered_at` string, required
      - `reading` string
      - `degraded` object: spec 1.4.0 (dg1): sources that could not be read when the answer was made: sources [{source, why}], reading, policy (the failure policy URL), policy_v. Present only when something was missing.
        - `sources` object[]
        - `policy` string
      - `assurance` 'partial': Present on just-in-time answers only. Full answers carry no assurance field.
      - `disputes` object: spec 1.4.0: open (being re-measured), filed, ledger; open > 0 adds the doubt disputed to read and cite
      - `status` 'measured' | 'partial' | 'not_measured' | 'opted_out' | 'withheld', required: withheld (dg1): the opt-out list could not be read, so nothing about the domain is served. partial (jit1): a domain CrawlCheck had never measured, read live the moment it was asked about; assurance is partial and upgrade says when the full scan replaces it
      - `why` string
      - `basis` object: Present when the answer comes from the daily census or a just-in-time read rather than a full scan record: kind, run, rank, measured_at, scope; just_in_time adds budget_ms, took_ms and not_read_in_budget (paths not read in time, never reported absent)
        - `kind` 'census' | 'just_in_time'
        - `run` integer, nullable
        - `measured_at` string, nullable
        - `scope` string
        - `budget_ms` integer
        - `took_ms` integer
        - `not_read_in_budget` string[]
      - `dns` object: jit1, just-in-time answers: A/AAAA/CNAME from Cloudflare DNS over HTTPS, rcode, exists, dnssec_validated (the resolver's AD flag)
      - `tls` object: jit1, just-in-time answers: whether the homepage fetch completed over HTTPS with a trusted certificate, final host, HSTS header
      - `upgrade` object: jit1, just-in-time answers: state queued, to full; the change feed records assurance partial → full when the full scan lands
      - `measurement` object
        - `requested` boolean
        - `first_request` boolean
        - `how` string
      - `subject` object
      - `freshness` object, nullable: observed_at, age_hours, fresh_until, stale, last_verified_at, fresh_policy (rsv3, provisional), plus latest_report_id / is_latest / newer_scan_exists
      - `observers` object
      - `rights` object, nullable: rgt1: one value per use (train, ground, summarize, cite, transact): allowed | denied | limited | restricted_by_terms | not_declared | unknown, each with decided_by {signal, url, evidence}, the signals considered and the conflicts between them; merged from robots.txt per agent, Content-Signal, ai.txt, TDM-Rep, robots meta, X-Robots-Tag and the terms page
      - `read_equivalence` object, nullable: req1: whether the main text served to AI identities (GPTBot, ClaudeBot, PerplexityBot) equals what a browser receives on the homepage: verdict equivalent|minor_differences|different|not_served|unverifiable, per-identity text_ratio, instruction_like_text; api link holds the differing sentences. The cite action warns with served_text_differs
      - `self_claims` object, nullable: scl1: what the site says about itself (telephone, email, address, hours, prices, refund window, founded, years in business, API rate limits), claims[] each with type, value, status current|withdrawn, first_seen, last_seen; changes are in the change feed as section self_claims; api link for evidence and pages read
      - `content_clock` object, nullable: clk2 (provisional): when the main content of the homepage (and of ?page= on the same site) last changed, from CrawlCheck's own reads: content_sha256, first_observed, main_content_last_changed {between, and}, declared dates, api link
      - `absences` object[]: sa1: what CrawlCheck looked for and did not find, each with what was requested (method, URL, status), the vantage, the time and a scope saying what the absence does and does not mean. Written only for definite answers (404/410, a finished registry import, a completed field read)
      - `mcp_registry` object: rsv4 (provisional): remote MCP servers the official MCP Registry lists on this domain and what each endpoint answered to the MCP handshake (listed, observed, initialized, auth_required, drifted, servers[])
      - `impersonation` object: spec 1.2.0: whether the domain looks built to be mistaken for a known brand (state, verdict, the brand frame it was compared against, and the technique when one is found)
      - `control` object: spec 1.3.0: whether control of the domain has been proven to CrawlCheck: state proven | unproven; proofs [{by: licence_holder | registry_claim, method: dns_txt | meta_tag | well_known_file | cloudflare_zone, how, since}]; organization {name, github, record} when its holder published one; claim (where to prove it) while unproven; why; note. Informational: it never changes a decision.
      - `transparency` object: spec 1.2.0: this answer's place in the append-only answer log: state (included or pending; pending with confirmed false means the lookup did not answer within the time budget and the proof URL settles it), log_id, leaf_hash, batch, index, the inclusion path and the signed tree head it folds to
      - `actions` object: rsv3 (provisional): read, cite, connect, transact, administer - each { decision: allow|warn|require_confirmation|block|unsupported, minimum_assurance, assurance_found[], needs, why, max_age_hours }, decided from this answer at signing time
      - `crawl_policy` ResolveV1Section
        - `state` 'declared' | 'observed' | 'not_measured', required
        - `observed_at` string, nullable, required
        - `why` string
      - `delivery` ResolveV1Section
        - `state` 'declared' | 'observed' | 'not_measured', required
        - `observed_at` string, nullable, required
        - `why` string
      - `machine_files` ResolveV1Section
        - `state` 'declared' | 'observed' | 'not_measured', required
        - `observed_at` string, nullable, required
        - `why` string
      - `capabilities` ResolveV1Section
        - `state` 'declared' | 'observed' | 'not_measured', required
        - `observed_at` string, nullable, required
        - `why` string
      - `entity` ResolveV1Section
        - `state` 'declared' | 'observed' | 'not_measured', required
        - `observed_at` string, nullable, required
        - `why` string
      - `findings` object
        - `access` string, required
        - `items` unknown[], required
          - unknown
      - `confidence` object, nullable
      - `contradictions` object, nullable
      - `evidence` object
      - `sha256` string, nullable, required
      - `signature` object, nullable, required
        - `alg` 'Ed25519'
        - `kid` string
        - `message` string
        - `sig` string
      - `unsigned` string
    - `error` union
      - object
      - string

## Other responses

- `400`: no domains, or more than 100

---

[API](https://skmtc.dev/crawlcheck/apis/crawlcheck-api.md) · [All operations](https://skmtc.dev/crawlcheck/apis/crawlcheck-api/llms.txt) · [OpenAPI document](https://skmtc.dev/crawlcheck/apis/crawlcheck-api/revisions/57acbd6d4489?raw)
