CrawlCheck

Specification · v1.1.0

Resolve protocol

What an AI agent should know about a domain before it acts on it, as one signed document. Any tool may read it, cache it, verify it offline and build on it. This page is the specification; the change log at the end is its history.

JSON Schema · API reference with worked examples · Offline verifier · Signing keys · Open observer protocol

1. Endpoints

MethodPathPurpose
GET/api/v1/resolve?domain=One signed ResolveV1 answer. Also /v1/resolve/{domain} and /api/v1/resolve/{domain}. Cached at the edge for 5 minutes.
POST/api/v1/resolveBatch: {"domains": [..]}, 1-100 names, one ResolveV1 per name in the order sent.
GET/api/v1/changes?since=Change feed: one event per section that moved when an answer was rebuilt. Poll with the last next_since; re-resolve only the domains listed.
POST/api/v1/outcomeAn agent reports what happened when it acted: status, blocked, challenged, and what the answer said beforehand. Self-reported; counted, never used to change an answer.
GET/api/v1/outcomes?domain=What agents reported for a domain over 30 days, including disagreements with the answer.
GET/api/v1/domain?domain=The domain's public registry record (RDAP) and its timeline.
GET/api/v1/accuracy?domain=What Google's AI states about a claimed business against what the business publishes.

MCP: the tool resolve_domain on https://crawlcheck.io/mcp returns the same document.

2. The document

kind: "crawlcheck-resolve", v: 1. status is measured, not_measured (an unknown domain; a measurement is requested) or opted_out. Each section carries state — declared (what the site says about itself), observed (what CrawlCheck was served) or not_measured — and observed_at. There is deliberately no overall score: an agent decides on the section its action depends on.

SectionAnswers
crawl_policyrobots.txt as declared, per crawler, with signal conflicts
deliverywhat each identity (browser, each AI crawler) was actually served: status, words, blocker, redirect
machine_filesllms.txt, sitemaps, well-known files: status and hashes
capabilitieswhat the site declares agents can do, by safety class, with verification and mismatches
entitywho the site says it is and whether external sources confirm it back
findingsopen findings, the top one in full without a licence
freshness, observers, confidence, contradictionshow old the reading is, from how many vantages, and where they disagree
evidencethe report, machine record and manifest this answer was built from

3. Signature

sha256 is the SHA-256 of the canonical JSON of every field except sha256 and signature (keys sorted at every level, no whitespace). signature.sig is Ed25519 over the message prefix crawlcheck-data-v1\n followed by that digest. The key is named by signature.kid and published in /.well-known/http-message-signatures-directory; retired keys stay listed so old answers still verify.

4. Verify offline

node crawlcheck-verify.mjs answer.json (Node 20+, no dependencies, no call to crawlcheck.io). It recomputes the digest, checks the signature against the published key and reports which check failed. Every answer, change batch, outcome tally and lifecycle record is also a leaf in that day’s Merkle root, anchored with OpenTimestamps; /api/seal/lookup?id=&day= says whether a leaf is in the sealed root.

5. Versioning

v in the document changes only when a field is removed or its meaning changes; such a change ships as a new version beside the old one, never in place. Added fields and added endpoints raise the minor number of this specification. Readers must ignore fields they do not know.

6. Change log

VersionDateChange
1.1.02026-10-03Added: path form GET /v1/resolve/{domain}; batch POST /api/v1/resolve (1-100 domains); change feed GET /api/v1/changes; agent outcome reports POST /api/v1/outcome and GET /api/v1/outcomes; domain lifecycle GET /api/v1/domain; AI accuracy GET /api/v1/accuracy. Answers, change batches, outcome tallies and lifecycle records join the daily sealed Merkle root. No field of ResolveV1 changed.
1.0.02026-10-02First publication: GET /api/v1/resolve, ResolveV1 document with declared / observed / not_measured sections and no overall score, Ed25519 signature, JSON Schema at /schemas/resolve.json, MCP tool resolve_domain, offline verifier.

Machine-readable: /spec/resolve.json