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

domainstring required
as_ofstring

ISO time: the answer that was in force then, as signed then (crawlcheck-resolve-as-of), with its in-force window and log inclusion proof; history from 7 Oct 2026

Response

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

kind'crawlcheck-resolve' required
vunknown required
schemastring
domainstring required
answered_atstring required
readingstring
assurance'partial'

Present on just-in-time answers only. Full answers carry no assurance field.

disputesobject

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

whystring
dnsobject

jit1, just-in-time answers: A/AAAA/CNAME from Cloudflare DNS over HTTPS, rcode, exists, dnssec_validated (the resolver's AD flag)

tlsobject

jit1, just-in-time answers: whether the homepage fetch completed over HTTPS with a trusted certificate, final host, HSTS header

upgradeobject

jit1, just-in-time answers: state queued, to full; the change feed records assurance partial → full when the full scan lands

subjectobject
freshnessobject nullable

observed_at, age_hours, fresh_until, stale, last_verified_at, fresh_policy (rsv3, provisional), plus latest_report_id / is_latest / newer_scan_exists

observersobject
rightsobject 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_equivalenceobject 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_claimsobject 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_clockobject 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

absencesobject[]

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_registryobject

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

impersonationobject

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)

controlobject

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.

transparencyobject

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

actionsobject

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

confidenceobject nullable
contradictionsobject nullable
evidenceobject
sha256string nullable required
unsignedstring

Changes

No recorded changes to this operation across all 1 revision of this API.