AttestPage · Docs · Pricing · OpenAPI · llms.txt

How to get a signed receipt of a web page

Last updated: 2026-10-10

To get a signed receipt of what a web page showed at a given time, have an independent fetcher load it and sign the result. POST /v1/fetch (US$0.002) loads the URL and returns an Ed25519-signed receipt with the final URL, status, time, content hash and a verdict on what came back. Anyone can check it offline.

What the receipt records

The receipt is a compact JWS (alg EdDSA). Its payload includes:

The full field list is in How it works.

Get one

{ "url": "https://www.iana.org/help/example-domains", "return_text": true }

Send that to POST /v1/fetch. With return_text you also get up to 20,000 characters of clean text. Try the route free first: [GET /v1/sample/fetch](https://vehcdj664efetfrsolne5umanq.srv.us/v1/sample/fetch). Details: Fetch a page. Step by step with curl, from the free sample to matching the page text: How to get a signed receipt of a web page, step by step with curl.

Pay per call with x402

No account or key is needed. A valid request with no payment gets 402 Payment Required with the price in a PAYMENT-REQUIRED header; an x402 v2 client signs that offer and sends the request again. With @x402/fetch (npm install @x402/fetch @x402/evm viem) and a Base Sepolia wallet made only for testing, holding test USDC:

import { wrapFetchWithPayment, x402Client } from '@x402/fetch';
import { registerExactEvmScheme } from '@x402/evm/exact/client';
import { privateKeyToAccount } from 'viem/accounts';

const client = new x402Client();
registerExactEvmScheme(client, { signer: privateKeyToAccount(process.env.ATTESTPAGE_X402_KEY) });
const payingFetch = wrapFetchWithPayment(fetch, client);

const res = await payingFetch('https://vehcdj664efetfrsolne5umanq.srv.us/v1/fetch', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ url: 'https://www.iana.org/help/example-domains', return_text: true }),
});
const answer = await res.json();
console.log(answer.page.content_kind, answer.page.content_sha256, answer.receipt);

The wrapper signs the offer it gets. To check the price and network before signing, see One x402 payment step by step.

Check one

Any receipt can be checked against our published keys with POST /v1/receipt/verify (free), or with no call to us at all:

curl -O https://vehcdj664efetfrsolne5umanq.srv.us/dl/verify-receipt.mjs
node verify-receipt.mjs --selftest

See Verify receipts offline. The keys are at /.well-known/jwks.json.

Receipts for other things

Questions

Is this the same as a web archive snapshot?

No. An archive stores the page for others to view. A receipt is a small signed statement about one fetch that you keep yourself; we do not publish it, and pages fetched for you are not stored (Privacy).

Does the receipt show the page is accurate?

No. It records what our fetcher saw at that time. Pages change and can show different content to different visitors.

Why would an agent want one?

To show later what a source said when it was used: when handing work to another agent, answering a dispute about a citation, or keeping an audit trail of the pages a task relied on.