AttestPage · Docs · Pricing · OpenAPI · llms.txt

Re-check a page against an earlier receipt

Last updated: 2026-10-15

POST /v1/recheck fetches the page named in an earlier receipt again and tells you whether its text changed: unchanged, changed, gone or unreadable, the fields that differ, and a signed receipt naming both the old and the new hashes. Price: US$0.003 per call.

When to use it

Request

Send exactly one of the two baseline forms. The receipt from an earlier call:

{ "receipt": "eyJhbGciOiJFZERTQSIs…", "return_text": false }

Or a URL and the content_sha256 from our own fetch of it:

{ "url": "https://www.iana.org/help/example-domains", "content_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "return_text": false }
FieldRequiredMeaning
receiptone of the two formscompact JWS receipt from an earlier /v1/fetch, /v1/verify/quote, /v1/verify/quotes or /v1/recheck call of this service, paid or trial (not a sample), at most 160 KB
urlone of the two formsonly without receipt: http or https URL, at most 2,048 characters
content_sha256with urlthe page.content_sha256 from our own fetch, 64 hex characters; other tools hash other text, so their hashes will not match
return_textnoalso return up to 20,000 characters of the new clean text; default false
quotenoonly with receipt from a verify/quote call in exact or fuzzy mode: the quote exactly as sent to verify/quote. Any other value is a 400 before payment
quotesnoonly with receipt from a verify/quotes call in exact or fuzzy mode: every quote of that call, exactly as sent, in the same order, 1 to 20. Not with quote. Any other value is a 400 before payment; on the edge it is a 501 not_on_edge, uncharged
historyno1 to 10 earlier receipts of this service for the same URL, oldest first (fetch, quote, quotes or recheck; paid or trial); adds a timeline. Not stored: send it again each time

The page fetched is the baseline's url (the URL first asked for, not the final URL), so redirects are followed again. The body may be up to 168 KB, so a long receipt fits.

History (timeline)

Send your own earlier receipts for the same URL in history and the answer gains a timeline: each receipt in order, then this check. changed on each entry compares its clean-text hash with the entry before it (null for the first, or when a hash is missing). A receipt that does not verify, names another URL or is out of order is a 400 baseline_invalid before payment, with its index. The timeline is also in the signed recheck receipt. Requests without history are unchanged.

Answer

From the free sample (GET /v1/sample/recheck), shortened:

{
  "change": "unchanged",
  "changed": false,
  "differences": [],
  "baseline": {
    "source": "caller",
    "receipt_sha256": null,
    "url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/page",
    "content_sha256": "0e429607…"
  },
  "elapsed_seconds": null,
  "page": {
    "final_url": "https://s2h6qt73jtzlgbgnnfacln2poq.srv.us/v1/sample/page",
    "http_status": 200,
    "content_kind": "real",
    "content_sha256": "0e429607…",
    "raw_sha256": "179b9ac4…"
  },
  "text": null,
  "injection_flags": [],
  "advice": "The page's text is the same as in the baseline (byte for byte on the clean text). Markup or other bytes may still have moved; see differences.",
  "receipt": "eyJhbGciOiJFZERTQSIs…",
  "tier": "paid",
  "rail": "x402",
  "network": "eip155:8453"
}
changechangedMeaning
unchangedfalseThe page's text is the same as in the baseline. A page already gone in the baseline and still gone is unchanged too.
changedtrueThe page's text differs from the baseline. Fetch it again or check your quote before you rely on it.
gonetrueThe page no longer exists (404 or 410, or the site's name no longer resolves).
unreadablenullWe could not read the page this time (page.content_kind says why), so we cannot say whether it changed. Try again later.

What "changed" means

The comparison is byte for byte on the clean text we extract (content_sha256). Markup-only changes are not changes: raw_sha256 may differ while the answer is unchanged. A page with a date, a counter or rotating text reads as changed on every visit. A content_sha256 from another tool will not match ours: use the hash from our own fetch.

Quote

With quote, the quote is matched on the live page again and the answer adds quote, with a verdict:

quote.verdictMeaning
still_exactThe quote was exact in the receipt and is exact now.
now_exactThe quote was fuzzy or not found in the receipt and is exact now.
now_fuzzyThe quote matches now only with small differences.
now_missingThe quote is not on the page now, and the page is real (page.content_kind).
uncheckedThe quote is not found on a page that is not real, so this says nothing about the quote.

With quotes (a verify/quotes receipt), each quote gets its own verdict in quotes, in the order sent: index, quote_sha256, verdict (the same values as above), was, now, score, start, end, occurrences, and error when that quote was too costly to match now (its verdict is then unchecked). If every quote is too costly, the call is a 422 match_too_costly, not charged.

Chaining

The recheck receipt is itself a valid baseline: send it to the next call. Its result.baseline.receipt_sha256 is the SHA-256 of the receipt you sent, so a chain can be checked offline with verify-receipt.mjs.

Charges and errors

The call is charged like /v1/fetch whenever it answers, gone and unreadable included: the fetch was done and the receipt is evidence of it. If we read no page at all (a timeout, a connect error, a bad decode, too many redirects or a redirect we refuse), the call answers 502 upstream_unreachable with details.reason set, and is not charged. Every baseline problem is a 400 before payment, never charged:

The other errors are those of /v1/fetch; see Errors. On the edge, a PDF page answers 501 not_on_edge, uncharged.

Compared with a hosted watch

No schedule, no webhook, nothing stored: you call when you want to know, and pay US$0.003 per check.