{"openapi":"3.1.0","info":{"title":"exhibit402","version":"1.0.0","description":"Proof of publication: permanently prove what a URL served at a moment in time. Two independent observers on different networks capture your URL at the same frozen instant; matching captures are CERTIFIED, the evidence is stored permanently, and an ERC-721 certificate carrying every observer hash is minted to the wallet that paid.","x-guidance":"POST /capture with a JSON body {url, mode} to permanently certify what a public web page served. Payment is USDC on Base (eip155:8453) via x402: $1.00 for mode 'fullpage' (default, whole page) or $0.50 for mode 'viewport' (first 1280x800 screen only; use it for pages with randomized below-fold content). Two independent standardized browsers (Google Cloud and Fly.io, same Los Angeles metro, different networks) capture the URL at one shared frozen timestamp. If both captures match byte-for-byte the certificate tier is CERTIFIED; if they differ after one retry round the tier is WITNESSED and the certificate includes the pixel agreement percentage, differing regions, and a diff map. Either way you receive: the canonical screenshot and a signed manifest stored permanently on Arweave (ar:// links plus IPFS CIDv1 and SHA-256 for independent verification), and an ERC-721 certificate on Base minted to the wallet that paid. The response is HTTP 202 with a claim URL; poll GET /claim/{job_id} (free) every ~15 seconds. Fulfillment normally takes 30-120 seconds, up to ~5 minutes with a cold observer or retry round. Refund policy, disclosed here and in the quote: captures rejected for oversize (PNG above 40MB), unreachable/never-idle pages, or by the content screen (illegal-to-distribute material, doxxing of private individuals) are refunded automatically minus a $0.10 processing fee; service faults are refunded in full. WITNESSED is a deliverable, not a failure, and is not refunded. The certificate is designed for evidence-grade use: fixed clock, pinned browser build, documented automated process (versioned system description referenced by SHA-256 from every manifest), hash-based identification, per-observer serving evidence (redirect chain, response headers, TLS chain, DNS answers, DOM), and an RFC 3161 timestamp token over the capture digest from an independent time-stamping authority.","contact":{"email":"dylan.caponi@gmail.com"}},"servers":[{"url":"https://exhibit402.dylan-caponi.workers.dev"}],"paths":{"/capture":{"post":{"operationId":"captureUrl","summary":"Certify what a URL serves right now ($1.00 fullpage / $0.50 viewport, returns a claim ticket)","tags":["Capture"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"1.000000"},"x-price-note":"$1.00 for fullpage, $0.50 for viewport; the 402 challenge quotes from your request body.","protocols":[{"x402":{}}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public http(s) URL to capture. Private/internal addresses are refused before payment.","examples":["https://en.wikipedia.org/wiki/SHA-2"]},"mode":{"type":"string","enum":["fullpage","viewport"],"description":"fullpage (default, $1.00) captures the whole page; viewport ($0.50) captures the first 1280x800 screen."}},"required":["url"]}}}},"responses":{"202":{"description":"Payment settled; capture running. Poll claim_url until final.","content":{"application/json":{"schema":{"type":"object","properties":{"job_id":{"type":"string"},"status":{"type":"string","enum":["processing"]},"claim_url":{"type":"string"},"check_after_seconds":{"type":"number"}},"required":["job_id","status","claim_url"]}}}},"400":{"description":"Invalid url or mode (you are not charged)"},"402":{"description":"Payment Required (USDC on Base)"}}}},"/claim/{job_id}":{"get":{"operationId":"getClaim","summary":"Retrieve the certificate for a paid capture (free, durable, no expiry)","tags":["Capture"],"security":[],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string"},"description":"The claim ticket returned by POST /capture"}],"responses":{"200":{"description":"Final result: {status:'done', tier, token_id, basescan_url, ar links, hashes, pixel_agreement_percent?} or a refund record per the disclosed policy."},"202":{"description":"Still processing; retry in ~15 seconds."},"404":{"description":"Unknown job_id"}}}},"/verify":{"get":{"operationId":"verifyCertificate","summary":"Re-verify any exhibit402 certificate ($0.02): recompute hashes against permanent storage and the chain","tags":["Verify"],"description":"Trust-but-verify for proof of publication. Pass the certificate's ERC-721 token id (digits), its Arweave manifest/metadata tx id (43 chars), or the exhibit402 job id (uuid). The service re-downloads the permanently stored screenshot and signed manifest from the Arweave gateway, recomputes every SHA-256 from the actual bytes, and compares against what the manifest claims and what the contract immutably recorded at mint (screenshotSha256, tokenURI, owner). The verdict is machine-readable: verified true/false plus a per-check breakdown (manifest_resolves, screenshot_hash, observer_agreement, onchain_sha256, rfc3161_timestamp). A false verdict is a delivered result and is charged; malformed ids and gateway outages return non-2xx and are not charged.","parameters":[{"name":"id","in":"query","required":true,"schema":{"type":"string"},"description":"ERC-721 token id, Arweave tx id, or exhibit402 job id","examples":{"token":{"value":"6"}}}],"responses":{"200":{"description":"Verification verdict","content":{"application/json":{"schema":{"type":"object","properties":{"verified":{"type":"boolean"},"tier":{"type":"string"},"url":{"type":"string"},"fixed_time":{"type":"string"},"token_id":{"type":"string"},"owner":{"type":"string"},"manifest_url":{"type":"string"},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"pass":{"type":"boolean"},"detail":{"type":"string"}}}},"note":{"type":"string"}},"required":["verified","checks","note"]}}}},"400":{"description":"Unrecognized id format (you are not charged)"},"402":{"description":"Payment Required (USDC on Base)"},"404":{"description":"No certificate found for that id (you are not charged)"},"502":{"description":"Storage gateway or RPC unavailable (you are not charged)"}}}}}}