---
title: "Before acting on a domain: one signed answer. Crawler policy as declared (robots.txt per crawler), delivery as observed per identity, machine files, capabilities with policy classes and certificate, entity reciprocity and the open findings (top one in full without a licence), each section declared/observed/not_measured with its time. No overall score. An unknown domain answers not_measured and a measurement is requested"
method: GET
path: "/api/v1/resolve"
tags: ["Core"]
---

# Before acting on a domain: one signed answer. Crawler policy as declared (robots.txt per crawler), delivery as observed per identity, machine files, capabilities with policy classes and certificate, entity reciprocity and the open findings (top one in full without a licence), each section declared/observed/not_measured with its time. No overall score. An unknown domain answers not_measured and a measurement is requested

`GET /api/v1/resolve`

## Request

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

## Query parameters

- `domain` string, required
- `as_of` string

## Response `200`

crawlcheck-resolve (ResolveV1, /schemas/resolve.json); verify offline with crawlcheck-verify.mjs

- 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

## Other responses

- `400`: no domain, an IP address, or a host that resolves to a private address

---

[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)
