{"openapi":"3.1.0","info":{"title":"Tollkit Attest","version":"0.27.0","description":"Signed, timestamped proof of what a web page said. Other Tollkit tools are described at: https://extract.tollkit.dev/openapi.json, https://web.tollkit.dev/openapi.json, https://chain.tollkit.dev/openapi.json, https://data.tollkit.dev/openapi.json.","x-guidance":"Call any operation with POST and the JSON body its schema shows. Without payment you get HTTP 402 with the exact price in USDC on Base or Solana; pay with any x402 client and repeat the request. Failed calls (any 4xx or 5xx) are never charged. Each operation's description says what it returns and which inputs are refused for free.","contact":{"email":"hello@tollkit.dev"}},"servers":[{"url":"https://attest.tollkit.dev"}],"paths":{"/attest":{"post":{"operationId":"attestPage","summary":"Signed, timestamped proof of what a page contained at a moment in time","description":"Prove what a web page said: signed, timestamped evidence of its text and screenshot, with hashes, the serving IP and TLS certificate. Anyone can verify it later, free. $0.05 per page; a page that fails to load is not charged.","tags":["Attestation"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Absolute https:// URL of the page to attest to. Anything a dispute could turn on: terms of service, a price, a published policy, a competitor's claim, a listing that may be edited later."},"screenshot":{"type":"boolean","default":true,"description":"Capture and hash a screenshot. On by default — an attestation without one is much weaker evidence. Turn it off for a faster, text-only record."}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","description":"A signed, timestamped record of what a page contained. The `attestation` object is the evidence; `content` holds the bytes its hashes are over. Store the whole response — this service keeps no copy, by design, so that the record cannot be altered or withdrawn later.","required":["attestation","content"],"properties":{"attestation":{"type":"object","required":["claim","digest","signature","signer"],"properties":{"claim":{"type":"object","description":"Exactly what was signed. Re-serialize this with sorted keys and no whitespace, keccak256 it, and you get `digest`.","properties":{"version":{"type":"integer"},"url":{"type":"string","description":"The URL as submitted."},"finalUrl":{"type":"string","description":"Where the browser ended up."},"redirected":{"type":"boolean"},"httpStatus":{"type":"integer"},"title":{"type":["string","null"]},"capturedAt":{"type":"string","description":"ISO 8601 render time."},"textSha256":{"type":"string"},"textLength":{"type":"integer"},"screenshotSha256":{"type":["string","null"]},"headers":{"type":"object","description":"Lowercased, sorted; set-cookie removed."},"remoteAddress":{"type":["string","null"],"description":"IP that served it."},"tlsIssuer":{"type":["string","null"]},"tlsSubject":{"type":["string","null"]},"tlsValidFrom":{"type":["string","null"]},"tlsValidTo":{"type":["string","null"]},"attestedBy":{"type":"string","description":"Signer address, inside the signed payload."}}},"digest":{"type":"string","description":"keccak256 of the canonical claim."},"signature":{"type":"string","description":"EIP-191 personal_sign over the digest."},"signer":{"type":"string"},"algorithm":{"type":"string"}}},"content":{"type":"object","properties":{"text":{"type":"string"},"textTruncated":{"type":"boolean"},"screenshotBase64":{"type":["string","null"]},"screenshotMimeType":{"type":["string","null"]}}},"verify":{"type":"string","description":"Free, unauthenticated verification endpoint."}}}}}},"400":{"description":"Bad input: a missing or malformed field, or a URL that is not public. Not charged.","content":{"application/json":{"schema":{"type":"object","required":["error","message","charged"],"properties":{"error":{"type":"string","description":"Machine-readable code, e.g. invalid_url, no_pool, page_fetch_failed."},"message":{"type":"string","description":"Plain-English reason, ending in \"Nothing was charged.\""},"charged":{"type":"boolean","const":false}}}}}},"402":{"description":"Payment Required. The PAYMENT-REQUIRED header carries the x402 v2 quote (price, asset, network, payTo) for each network accepted. Pay and retry with PAYMENT-SIGNATURE."},"422":{"description":"Valid input the tool could not answer, e.g. an empty page, a token with no pool, an unknown ticker. Not charged.","content":{"application/json":{"schema":{"type":"object","required":["error","message","charged"],"properties":{"error":{"type":"string","description":"Machine-readable code, e.g. invalid_url, no_pool, page_fetch_failed."},"message":{"type":"string","description":"Plain-English reason, ending in \"Nothing was charged.\""},"charged":{"type":"boolean","const":false}}}}}},"429":{"description":"Too many requests from this caller; retry after a short wait. Not charged.","content":{"application/json":{"schema":{"type":"object","required":["error","message","charged"],"properties":{"error":{"type":"string","description":"Machine-readable code, e.g. invalid_url, no_pool, page_fetch_failed."},"message":{"type":"string","description":"Plain-English reason, ending in \"Nothing was charged.\""},"charged":{"type":"boolean","const":false}}}}}},"502":{"description":"An upstream source (the page, a chain RPC, a public data API) failed or timed out. Not charged; safe to retry.","content":{"application/json":{"schema":{"type":"object","required":["error","message","charged"],"properties":{"error":{"type":"string","description":"Machine-readable code, e.g. invalid_url, no_pool, page_fetch_failed."},"message":{"type":"string","description":"Plain-English reason, ending in \"Nothing was charged.\""},"charged":{"type":"boolean","const":false}}}}}},"503":{"description":"The tool is temporarily unavailable on this deployment. Not charged.","content":{"application/json":{"schema":{"type":"object","required":["error","message","charged"],"properties":{"error":{"type":"string","description":"Machine-readable code, e.g. invalid_url, no_pool, page_fetch_failed."},"message":{"type":"string","description":"Plain-English reason, ending in \"Nothing was charged.\""},"charged":{"type":"boolean","const":false}}}}}}}}},"/attest/verify":{"post":{"operationId":"verifyAttestation","summary":"Free. Re-hash an attestation and check its signature. No account, forever.","tags":["Attestation"],"security":[],"responses":{"200":{"description":"Verification result"}}}},"/attest/signer":{"get":{"operationId":"attestSigner","summary":"Free. The address attestations are signed by. Pin it.","tags":["Attestation"],"security":[],"responses":{"200":{"description":"Signer address and algorithm"}}}}}}