Verify a decision offline
Signed receipts bind every returned decision field.
Live features and staging previews are distinguished. Index coverage is not yet available.
Trust the key first
Obtain /.well-known/spendpreflight-keys.json over the trusted service origin and pin it separately. A key supplied by an untrusted receipt sender is not an identity proof. verifyReceipt (JS) and verify_receipt/verifyReceipt (Python) perform no network request. The full response, including reasons, chosen option and receipt/input hash, must match the JWS.
// Pass verifyReceipt from the published 0.2.0 SDK and a separately trusted key set.
// No automatic key fetch, receipt persistence or payment occurs here.
export async function checkedDecision(response, trustedKeys, verifyReceipt, options = {}) {
const verified = await verifyReceipt(response, trustedKeys, options);
if (!verified.valid) return "hold";
return verified.decision; // caller still enforces hold/block before payment
}
Download tested sourceTime and rotation
Default maximum age is one hour with 60 seconds clock tolerance. Explicit archival mode removes only the age requirement; it does not make an old decision current. Save public keys with receipts and refresh revocations. Signature validity is our statement, not a guarantee, caller identity check or paid-settlement proof. JWS is readable, so keep receipts private.
x402 delivery receipts
The paid HTTP preflight route uses the official offer-receipt extension as well. Its signed offer commits payment terms; its separate delivery receipt follows settlement. Trial and MCP decisions have the decision-body JWS without any fabricated paid-delivery proof. No receipt history or caller request bodies are stored by this service.