{"openapi":"3.1.0","info":{"title":"presign-guard","version":"2.5.0","termsOfService":"https://fizzl.eu/terms/","contact":{"name":"Fizzl","url":"https://fizzl.eu","email":"Fizzl13@protonmail.com"},"description":"Pre-sign risk check for AI agents: a green/orange/red verdict with reason codes before signing an EVM transaction, approval or EIP-712 signature, a Solana transaction (every instruction decoded, then simulated), an XRP Ledger transaction or an Algorand transaction or group (simulated). Checks the spender or recipient (including OFAC SDN sanctions), the token itself (honeypot, impersonation, high tax) and, with origin, how old the requesting site's domain is. Plus GET /v1/token: a verdict on any Solana or EVM token before buying, holding or accepting it, GET /v1/approvals: an audit of a wallet's open token approvals with the ones to revoke, and GET /v1/screen: any chain's wallet address against the OFAC SDN sanctions list. Every paid answer carries a signed receipt (EIP-191) binding the verdict to your request, verifiable later.","x-guidance":"Call POST /v1/check with what you are about to sign, before you sign it. Only proceed on green; on orange ask your user; never sign on red. For a signature, pass the exact eth_signTypedData_v4 payload as typedData. Pass origin (the site asking) to catch newly registered phishing domains, and intent (one sentence: what you are trying to do) to catch signing something else than you meant (INTENT_MISMATCH). For a transaction, pass from (your wallet) so it is simulated: you see what really leaves your wallet. For a Solana transaction, send type solana with the base64 wire transaction as transaction: it is decoded and simulated, and a token account handed to someone else is red. For an XRP Ledger transaction, send type xrpl with the unsigned transaction JSON as tx: a new regular key or signer list, a disabled master key, AccountDelete or fake RLUSD is red. For Algorand, send type algorand with the base64 msgpack transaction as transaction (or a whole group as transactions): a rekey, closing the account or an asset holding to someone else, or fake USDC is red. Paying an x402 challenge? Pass the accepts entry you chose as x402 to catch a signature that pays more, someone else or another token than the seller asked. Use /v1/check/explain when a person needs the reason in plain language (lang en or nl). Before buying or accepting a token, call GET /v1/token?chain=solana&address=<mint> (or chain=base with a 0x address, chain=algorand with an asset id): the same green/orange/red logic plus a grade, a one-line summary and market data. To clean up a wallet, call GET /v1/approvals?chain=base&address=<wallet>: every open token approval with who the spender is, and which ones to revoke. Before paying an address or accepting money from one, call GET /v1/screen?address=<address> (any chain: EVM, Solana, Tron, Bitcoin, XRP Ledger, Algorand): red when it is on the OFAC SDN list or reported for theft or phishing. Keep the receipt field of each answer: it is signed by the address at /.well-known/presign-guard-signer.json and proves which verdict you got for which request; POST /v1/verify checks one for free. Calling often? Buy prepaid credits once (GET /v1/credits/100 for $0.80 or /v1/credits/1000 for $7.00, 1 credit = $0.01) and send the returned key in the x-credit-key header instead of paying per call; GET /v1/credits shows prices and, with the header, your balance. When the credits run out you get the normal 402."},"servers":[{"url":"https://presign-guard.fizzl.eu"}],"paths":{"/v1/check":{"post":{"operationId":"check","summary":"Check if a transaction, approval or signature is safe to sign","tags":["Pre-sign checks"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"x402":{}},{"mpp":{"method":"evm","intent":"charge","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"mpp":{"method":"tempo","intent":"session","currency":"0x20C000000000000000000000b9537d11c60E8b50"}}],"networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","xrpl:0","algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","stellar:pubnet"],"asset":"USDC","offers":[{"amount":"10000","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","description":"Check if a transaction, approval or signature is safe to sign","intent":"charge","method":"evm"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a transaction, approval or signature is safe to sign","intent":"charge","method":"tempo"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a transaction, approval or signature is safe to sign","intent":"session","method":"tempo","unitType":"request"}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["approval","transaction","signature","message","solana","xrpl","algorand"],"description":"What the agent is about to sign (message: a plain personal_sign / eth_sign message; solana: a Solana transaction; xrpl: an XRP Ledger transaction; algorand: an Algorand transaction or group)"},"transaction":{"type":"string","maxLength":12000,"description":"algorand: one base64 msgpack transaction (unsigned or signed); red ALGORAND_REKEY, ALGORAND_CLOSE_ACCOUNT, ALGORAND_ASSET_CLOSE, ALGORAND_FAKE_STABLECOIN; simulated. solana: the base64 wire transaction about to be signed (legacy or v0). Decoded and simulated: red SOLANA_TOKEN_ACCOUNT_TAKEOVER (SetAuthority hands a token account to someone else) and SOLANA_ACCOUNT_ASSIGN (the wallet handed to a program); orange SOLANA_UNLIMITED_DELEGATE, SOLANA_DURABLE_NONCE, SOLANA_CLOSE_TO_OTHER, HIDDEN_APPROVAL, SIMULATION_FAILS. from (optional) names the wallet if it is not the fee payer"},"transactions":{"type":"array","maxItems":16,"items":{"type":"string"},"description":"algorand: an atomic group, each base64 msgpack; send the whole group"},"method":{"type":"string","enum":["personal_sign","eth_sign"],"description":"message: how it is signed (default personal_sign); eth_sign is always red"},"message":{"type":"string","maxLength":16384,"description":"message: the text or 0x-hex about to be signed. A Sign-In with Ethereum message for another site than origin is red (SIGN_IN_DOMAIN_MISMATCH), unreadable bytes are orange"},"chainId":{"type":"integer","enum":[1,10,56,137,8453,42161],"description":"EVM chain; required for approval, transaction and signature"},"network":{"type":"string","enum":["xrpl:0","xrpl:1"],"description":"xrpl: the ledger (default xrpl:0, mainnet)"},"tx":{"type":"object","description":"xrpl: the unsigned transaction JSON (TransactionType, Account, ...). Red: SetRegularKey/SignerListSet to another key, disabling the master key, AccountDelete, fake RLUSD; orange: partial payments, destinations that refuse or need a tag, issuers that can claw back or freeze, escrows and NFT giveaways"},"token":{"type":"string","description":"approval: token contract"},"spender":{"type":"string","description":"approval: who gets the allowance"},"amount":{"type":"string","description":"approval: amount in base units (0 = revoke)"},"to":{"type":"string","description":"transaction: target contract"},"data":{"type":"string","description":"transaction: 0x-prefixed calldata"},"value":{"type":"string","description":"transaction: native value in wei"},"from":{"type":"string","description":"transaction, optional: the wallet that would send it. With it the transaction is simulated (eth_simulateV1 on all six chains): the answer gets a simulation field with every asset that leaves or arrives, orange HIDDEN_APPROVAL (an approval the call does not show, e.g. inside a router or batch), SIMULATION_NFT_OUT or SIMULATION_FAILS, and the intent check compares your intent with the real balance changes. algorand: the wallet, if not the first transaction's sender. A recipient that looks like an address this wallet paid before but isn't it is red ADDRESS_POISONING"},"typedData":{"type":["object","string"],"description":"signature: the eth_signTypedData_v4 payload (Permit, Permit2, EIP-3009 x402 payment, Seaport)"},"origin":{"type":"string","description":"optional: the site asking for the signature or transaction (URL or hostname); a domain under 30 days old is orange"},"intent":{"type":"string","maxLength":500,"description":"optional: what the agent is trying to do, in one sentence (e.g. \"swap 10 USDC for ETH on Uniswap\"); orange INTENT_MISMATCH when signing would do more or something else (TypeSafe Jev)"},"x402":{"type":"object","description":"optional, EIP-3009 payments only: the x402 payment requirements the agent is paying, one entry of the 402 challenge's accepts list, as { accepted: { scheme, network, amount, asset, payTo, maxTimeoutSeconds, extra } } or the entry itself. Red X402_AMOUNT_ABOVE_REQUIRED, X402_RECIPIENT_MISMATCH, X402_ASSET_MISMATCH or X402_NETWORK_MISMATCH when the signature does not pay exactly what the seller asked; orange X402_VALIDITY_TOO_LONG when it stays valid far beyond the seller's timeout (a bearer authorization), X402_DOMAIN_MISMATCH, X402_SCHEME_UNEXPECTED"},"mandate":{"type":"object","description":"optional, EIP-3009 payments only: the spending mandate the agent pays under (x402 authority extension, x402-mandate/1): { mandate, alg: \"Ed25519\", sig, paymentId }. Outside it (over perPayment or cap, other recipient, payer or token, expired, bad signature, nonce not the mandate binding) is red"},"lang":{"type":"string","enum":["en","nl"],"description":"explain only: language of the explanation (default en)"}},"required":["type"],"allOf":[{"if":{"properties":{"type":{"enum":["approval","transaction","signature"]}},"required":["type"]},"then":{"required":["chainId"]}},{"if":{"properties":{"type":{"const":"solana"}},"required":["type"]},"then":{"required":["transaction"]}},{"if":{"properties":{"type":{"const":"algorand"}},"required":["type"]},"then":{"anyOf":[{"required":["transaction"]},{"required":["transactions"]}]}},{"if":{"properties":{"type":{"const":"xrpl"}},"required":["type"]},"then":{"required":["tx"]}},{"if":{"properties":{"type":{"const":"message"}},"required":["type"]},"then":{"required":["message"]}}]},"example":{"type":"approval","chainId":8453,"token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","spender":"0x000000000022D473030F116dDEE9F6B43aC78BA3","amount":"1000000"}}}},"responses":{"200":{"description":"Verdict","content":{"application/json":{"schema":{"type":"object","properties":{"verdict":{"type":"string","enum":["green","orange","red"]},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["red","orange","info"]},"subject":{"type":"string"},"details":{}},"required":["code","severity"]}},"subject":{"type":"object"},"explanation":{"type":"object","properties":{"lang":{"type":"string"},"text":{"type":"string"}}},"receipt":{"type":"object","description":"Signature over this whole answer (without receipt.signature), so the verdict can be verified later: EIP-191 personal_sign over canonical JSON (sorted keys, compact, ASCII-escaped). Signer addresses: /.well-known/presign-guard-signer.json; free check: POST /v1/verify.","properties":{"request_id":{"type":"string"},"route":{"type":"string"},"input_sha256":{"type":"string","description":"sha256 of canonical JSON {route, input}: your body (POST) or query parameters (GET)"},"payment":{"type":"object","description":"The payment behind this answer, from your x402 payment payload. EVM: payer + EIP-3009 nonce; find the settlement as AuthorizationUsed(payer, nonce) on the asset contract. Solana: payer + sha256 of the signed transaction you sent.","properties":{"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"pay_to":{"type":"string"},"payer":{"type":"string"},"nonce":{"type":"string"},"transaction_sha256":{"type":"string"},"proof":{"type":"string","enum":["eip3009","svm-transaction"]}}},"cert":{"type":"object","description":"The payout wallet's certificate for this signing key: personal_sign by authority over 'fizzl receipt signer\\nservice: <service>\\nsigner: <signer>\\nvalid_from: <date>'. Pin the payout wallet and a rotated key still verifies.","properties":{"service":{"type":"string"},"signer":{"type":"string"},"valid_from":{"type":"string"},"authority":{"type":"string"},"signature":{"type":"string"}}},"signed_at":{"type":"string"},"signer":{"type":"string"},"algorithm":{"type":"string","enum":["eip191-canonical-json-v1"]},"signature":{"type":"string"}},"required":["request_id","route","input_sha256","signed_at","signer","algorithm","signature"]},"simulation":{"type":"object","description":"What the transaction would do, from a simulation: an EVM transaction sent with from, or a Solana transaction. Missing when it could not be simulated","properties":{"ok":{"type":"boolean","description":"false: the transaction would fail (error says why)"},"error":{"type":"string"},"changes":{"type":"array","maxItems":50,"description":"EVM: transfers and approvals in the order they happen. Solana: the changes of the wallet and its token accounts","items":{"type":"object","properties":{"type":{"type":"string","enum":["transfer","approve","sol","token","closed","owner","delegate"],"description":"EVM: transfer, approve. Solana: sol, token, closed (a token account closed), owner (an account handed to another owner or program), delegate"},"asset":{"type":"string","enum":["native","erc20","erc721","erc1155","nft_all"],"description":"EVM: what moves or is approved"},"token":{"type":"string","description":"EVM: the token contract"},"symbol":{"type":"string","description":"EVM: the token symbol, when known"},"from":{"type":"string","description":"EVM: sender or owner. Solana owner change: the old owner"},"to":{"type":"string","description":"EVM: recipient or spender. Solana owner change: the new owner"},"rawAmount":{"type":"string","description":"EVM: the amount in base units"},"amount":{"type":["string","null"],"description":"EVM: the amount in token units, when the decimals are known. Solana delegate: the delegated amount"},"tokenId":{"type":"string","description":"EVM: the NFT id"},"account":{"type":"string","description":"Solana: the account that changes (the wallet or one of its token accounts)"},"mint":{"type":"string","description":"Solana: the token mint"},"change":{"type":"number","description":"Solana: the change in SOL (sol) or in token units (token); negative when it leaves"},"lamports":{"type":"string","description":"Solana sol: the exact change in lamports"},"raw":{"type":"string","description":"Solana token: the exact change in base units"},"decimals":{"type":"integer","description":"Solana token: the mint's decimals"},"delegate":{"type":"string","description":"Solana delegate: who may now spend from the token account"}},"required":["type"]}},"partial":{"type":"boolean","description":"Solana: the transaction writes more accounts than were read, so changes may be incomplete"},"fee":{"type":"number","description":"Solana: the network fee in SOL"},"lookupTableAccounts":{"type":"integer","description":"Solana: accounts loaded from address lookup tables"},"gasUsed":{"type":"string","description":"EVM: gas used"},"source":{"type":"string","description":"EVM: the RPC that simulated it"}},"required":["ok","changes"]}},"required":["verdict","reasons"]},"example":{"verdict":"orange","reasons":[{"code":"UNLIMITED_APPROVAL","severity":"orange","subject":"0x000000000022d473030f116ddee9f6b43ac78ba3","details":{"token":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"}}]}}}},"400":{"description":"Invalid request; nothing is charged"},"402":{"description":"Payment Required"},"503":{"description":"A data source is down; nothing is charged, no verdict"}}}},"/v1/check/explain":{"post":{"operationId":"checkAndExplain","summary":"Get a pre-sign verdict with a plain-language explanation","tags":["Pre-sign checks"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.03"},"protocols":[{"x402":{}},{"mpp":{"method":"evm","intent":"charge","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"mpp":{"method":"tempo","intent":"session","currency":"0x20C000000000000000000000b9537d11c60E8b50"}}],"networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","xrpl:0","algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","stellar:pubnet"],"asset":"USDC","offers":[{"amount":"30000","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","description":"Get a pre-sign verdict with a plain-language explanation","intent":"charge","method":"evm"},{"amount":"30000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Get a pre-sign verdict with a plain-language explanation","intent":"charge","method":"tempo"},{"amount":"30000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Get a pre-sign verdict with a plain-language explanation","intent":"session","method":"tempo","unitType":"request"}]},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["approval","transaction","signature","message","solana","xrpl","algorand"],"description":"What the agent is about to sign (message: a plain personal_sign / eth_sign message; solana: a Solana transaction; xrpl: an XRP Ledger transaction; algorand: an Algorand transaction or group)"},"transaction":{"type":"string","maxLength":12000,"description":"algorand: one base64 msgpack transaction (unsigned or signed); red ALGORAND_REKEY, ALGORAND_CLOSE_ACCOUNT, ALGORAND_ASSET_CLOSE, ALGORAND_FAKE_STABLECOIN; simulated. solana: the base64 wire transaction about to be signed (legacy or v0). Decoded and simulated: red SOLANA_TOKEN_ACCOUNT_TAKEOVER (SetAuthority hands a token account to someone else) and SOLANA_ACCOUNT_ASSIGN (the wallet handed to a program); orange SOLANA_UNLIMITED_DELEGATE, SOLANA_DURABLE_NONCE, SOLANA_CLOSE_TO_OTHER, HIDDEN_APPROVAL, SIMULATION_FAILS. from (optional) names the wallet if it is not the fee payer"},"transactions":{"type":"array","maxItems":16,"items":{"type":"string"},"description":"algorand: an atomic group, each base64 msgpack; send the whole group"},"method":{"type":"string","enum":["personal_sign","eth_sign"],"description":"message: how it is signed (default personal_sign); eth_sign is always red"},"message":{"type":"string","maxLength":16384,"description":"message: the text or 0x-hex about to be signed. A Sign-In with Ethereum message for another site than origin is red (SIGN_IN_DOMAIN_MISMATCH), unreadable bytes are orange"},"chainId":{"type":"integer","enum":[1,10,56,137,8453,42161],"description":"EVM chain; required for approval, transaction and signature"},"network":{"type":"string","enum":["xrpl:0","xrpl:1"],"description":"xrpl: the ledger (default xrpl:0, mainnet)"},"tx":{"type":"object","description":"xrpl: the unsigned transaction JSON (TransactionType, Account, ...). Red: SetRegularKey/SignerListSet to another key, disabling the master key, AccountDelete, fake RLUSD; orange: partial payments, destinations that refuse or need a tag, issuers that can claw back or freeze, escrows and NFT giveaways"},"token":{"type":"string","description":"approval: token contract"},"spender":{"type":"string","description":"approval: who gets the allowance"},"amount":{"type":"string","description":"approval: amount in base units (0 = revoke)"},"to":{"type":"string","description":"transaction: target contract"},"data":{"type":"string","description":"transaction: 0x-prefixed calldata"},"value":{"type":"string","description":"transaction: native value in wei"},"from":{"type":"string","description":"transaction, optional: the wallet that would send it. With it the transaction is simulated (eth_simulateV1 on all six chains): the answer gets a simulation field with every asset that leaves or arrives, orange HIDDEN_APPROVAL (an approval the call does not show, e.g. inside a router or batch), SIMULATION_NFT_OUT or SIMULATION_FAILS, and the intent check compares your intent with the real balance changes. algorand: the wallet, if not the first transaction's sender. A recipient that looks like an address this wallet paid before but isn't it is red ADDRESS_POISONING"},"typedData":{"type":["object","string"],"description":"signature: the eth_signTypedData_v4 payload (Permit, Permit2, EIP-3009 x402 payment, Seaport)"},"origin":{"type":"string","description":"optional: the site asking for the signature or transaction (URL or hostname); a domain under 30 days old is orange"},"intent":{"type":"string","maxLength":500,"description":"optional: what the agent is trying to do, in one sentence (e.g. \"swap 10 USDC for ETH on Uniswap\"); orange INTENT_MISMATCH when signing would do more or something else (TypeSafe Jev)"},"x402":{"type":"object","description":"optional, EIP-3009 payments only: the x402 payment requirements the agent is paying, one entry of the 402 challenge's accepts list, as { accepted: { scheme, network, amount, asset, payTo, maxTimeoutSeconds, extra } } or the entry itself. Red X402_AMOUNT_ABOVE_REQUIRED, X402_RECIPIENT_MISMATCH, X402_ASSET_MISMATCH or X402_NETWORK_MISMATCH when the signature does not pay exactly what the seller asked; orange X402_VALIDITY_TOO_LONG when it stays valid far beyond the seller's timeout (a bearer authorization), X402_DOMAIN_MISMATCH, X402_SCHEME_UNEXPECTED"},"mandate":{"type":"object","description":"optional, EIP-3009 payments only: the spending mandate the agent pays under (x402 authority extension, x402-mandate/1): { mandate, alg: \"Ed25519\", sig, paymentId }. Outside it (over perPayment or cap, other recipient, payer or token, expired, bad signature, nonce not the mandate binding) is red"},"lang":{"type":"string","enum":["en","nl"],"description":"explain only: language of the explanation (default en)"}},"required":["type"],"allOf":[{"if":{"properties":{"type":{"enum":["approval","transaction","signature"]}},"required":["type"]},"then":{"required":["chainId"]}},{"if":{"properties":{"type":{"const":"solana"}},"required":["type"]},"then":{"required":["transaction"]}},{"if":{"properties":{"type":{"const":"algorand"}},"required":["type"]},"then":{"anyOf":[{"required":["transaction"]},{"required":["transactions"]}]}},{"if":{"properties":{"type":{"const":"xrpl"}},"required":["type"]},"then":{"required":["tx"]}},{"if":{"properties":{"type":{"const":"message"}},"required":["type"]},"then":{"required":["message"]}}]},"example":{"type":"approval","chainId":8453,"token":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","spender":"0x000000000022D473030F116dDEE9F6B43aC78BA3","amount":"1000000"}}}},"responses":{"200":{"description":"Verdict","content":{"application/json":{"schema":{"type":"object","properties":{"verdict":{"type":"string","enum":["green","orange","red"]},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["red","orange","info"]},"subject":{"type":"string"},"details":{}},"required":["code","severity"]}},"subject":{"type":"object"},"explanation":{"type":"object","properties":{"lang":{"type":"string"},"text":{"type":"string"}}},"receipt":{"type":"object","description":"Signature over this whole answer (without receipt.signature), so the verdict can be verified later: EIP-191 personal_sign over canonical JSON (sorted keys, compact, ASCII-escaped). Signer addresses: /.well-known/presign-guard-signer.json; free check: POST /v1/verify.","properties":{"request_id":{"type":"string"},"route":{"type":"string"},"input_sha256":{"type":"string","description":"sha256 of canonical JSON {route, input}: your body (POST) or query parameters (GET)"},"payment":{"type":"object","description":"The payment behind this answer, from your x402 payment payload. EVM: payer + EIP-3009 nonce; find the settlement as AuthorizationUsed(payer, nonce) on the asset contract. Solana: payer + sha256 of the signed transaction you sent.","properties":{"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"pay_to":{"type":"string"},"payer":{"type":"string"},"nonce":{"type":"string"},"transaction_sha256":{"type":"string"},"proof":{"type":"string","enum":["eip3009","svm-transaction"]}}},"cert":{"type":"object","description":"The payout wallet's certificate for this signing key: personal_sign by authority over 'fizzl receipt signer\\nservice: <service>\\nsigner: <signer>\\nvalid_from: <date>'. Pin the payout wallet and a rotated key still verifies.","properties":{"service":{"type":"string"},"signer":{"type":"string"},"valid_from":{"type":"string"},"authority":{"type":"string"},"signature":{"type":"string"}}},"signed_at":{"type":"string"},"signer":{"type":"string"},"algorithm":{"type":"string","enum":["eip191-canonical-json-v1"]},"signature":{"type":"string"}},"required":["request_id","route","input_sha256","signed_at","signer","algorithm","signature"]},"simulation":{"type":"object","description":"What the transaction would do, from a simulation: an EVM transaction sent with from, or a Solana transaction. Missing when it could not be simulated","properties":{"ok":{"type":"boolean","description":"false: the transaction would fail (error says why)"},"error":{"type":"string"},"changes":{"type":"array","maxItems":50,"description":"EVM: transfers and approvals in the order they happen. Solana: the changes of the wallet and its token accounts","items":{"type":"object","properties":{"type":{"type":"string","enum":["transfer","approve","sol","token","closed","owner","delegate"],"description":"EVM: transfer, approve. Solana: sol, token, closed (a token account closed), owner (an account handed to another owner or program), delegate"},"asset":{"type":"string","enum":["native","erc20","erc721","erc1155","nft_all"],"description":"EVM: what moves or is approved"},"token":{"type":"string","description":"EVM: the token contract"},"symbol":{"type":"string","description":"EVM: the token symbol, when known"},"from":{"type":"string","description":"EVM: sender or owner. Solana owner change: the old owner"},"to":{"type":"string","description":"EVM: recipient or spender. Solana owner change: the new owner"},"rawAmount":{"type":"string","description":"EVM: the amount in base units"},"amount":{"type":["string","null"],"description":"EVM: the amount in token units, when the decimals are known. Solana delegate: the delegated amount"},"tokenId":{"type":"string","description":"EVM: the NFT id"},"account":{"type":"string","description":"Solana: the account that changes (the wallet or one of its token accounts)"},"mint":{"type":"string","description":"Solana: the token mint"},"change":{"type":"number","description":"Solana: the change in SOL (sol) or in token units (token); negative when it leaves"},"lamports":{"type":"string","description":"Solana sol: the exact change in lamports"},"raw":{"type":"string","description":"Solana token: the exact change in base units"},"decimals":{"type":"integer","description":"Solana token: the mint's decimals"},"delegate":{"type":"string","description":"Solana delegate: who may now spend from the token account"}},"required":["type"]}},"partial":{"type":"boolean","description":"Solana: the transaction writes more accounts than were read, so changes may be incomplete"},"fee":{"type":"number","description":"Solana: the network fee in SOL"},"lookupTableAccounts":{"type":"integer","description":"Solana: accounts loaded from address lookup tables"},"gasUsed":{"type":"string","description":"EVM: gas used"},"source":{"type":"string","description":"EVM: the RPC that simulated it"}},"required":["ok","changes"]}},"required":["verdict","reasons"]},"example":{"verdict":"orange","reasons":[{"code":"UNLIMITED_APPROVAL","severity":"orange","subject":"0x000000000022d473030f116ddee9f6b43ac78ba3","details":{"token":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"}}]}}}},"400":{"description":"Invalid request; nothing is charged"},"402":{"description":"Payment Required"},"503":{"description":"A data source is down; nothing is charged, no verdict"}}}},"/v1/token":{"get":{"operationId":"tokenVerdict","summary":"Check if a token is safe to buy, hold or accept (Solana, EVM)","tags":["Token checks"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"x402":{}},{"mpp":{"method":"evm","intent":"charge","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"mpp":{"method":"tempo","intent":"session","currency":"0x20C000000000000000000000b9537d11c60E8b50"}}],"networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","xrpl:0","algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","stellar:pubnet"],"asset":"USDC","offers":[{"amount":"10000","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","description":"Check if a token is safe to buy, hold or accept (Solana, EVM)","intent":"charge","method":"evm"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a token is safe to buy, hold or accept (Solana, EVM)","intent":"charge","method":"tempo"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a token is safe to buy, hold or accept (Solana, EVM)","intent":"session","method":"tempo","unitType":"request"}]},"parameters":[{"name":"chain","in":"query","required":true,"schema":{"type":"string","enum":["solana","base","ethereum","arbitrum","optimism","polygon","bsc","xrpl","algorand"],"description":"Chain the token lives on"},"example":"solana"},{"name":"address","in":"query","required":true,"schema":{"type":"string","description":"Solana mint address (base58), EVM token contract (0x...), an XRPL token as CURRENCY.rIssuer (e.g. RLUSD.rMxCKbEDwqr76QuheSUMdEGf4B9xJ8m5De), or an Algorand asset id (e.g. 31566704)"},"example":"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"}],"responses":{"200":{"description":"Verdict","content":{"application/json":{"schema":{"type":"object","properties":{"verdict":{"type":"string","enum":["green","orange","red"]},"grade":{"type":"string","enum":["SAFE","CAUTION","RISKY","AVOID"]},"one_liner":{"type":"string"},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["red","orange","info"]},"details":{}},"required":["code","severity"]}},"token":{"type":"object"},"market":{"type":["object","null"],"description":"DexScreener data: priceUsd, liquidityUsd, marketCapUsd, volume24hUsd, firstPairAt, ageSeconds, url"},"sources":{"type":"array","items":{"type":"string"}},"checkedAt":{"type":"string"},"receipt":{"type":"object","description":"Signature over this whole answer (without receipt.signature), so the verdict can be verified later: EIP-191 personal_sign over canonical JSON (sorted keys, compact, ASCII-escaped). Signer addresses: /.well-known/presign-guard-signer.json; free check: POST /v1/verify.","properties":{"request_id":{"type":"string"},"route":{"type":"string"},"input_sha256":{"type":"string","description":"sha256 of canonical JSON {route, input}: your body (POST) or query parameters (GET)"},"payment":{"type":"object","description":"The payment behind this answer, from your x402 payment payload. EVM: payer + EIP-3009 nonce; find the settlement as AuthorizationUsed(payer, nonce) on the asset contract. Solana: payer + sha256 of the signed transaction you sent.","properties":{"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"pay_to":{"type":"string"},"payer":{"type":"string"},"nonce":{"type":"string"},"transaction_sha256":{"type":"string"},"proof":{"type":"string","enum":["eip3009","svm-transaction"]}}},"cert":{"type":"object","description":"The payout wallet's certificate for this signing key: personal_sign by authority over 'fizzl receipt signer\\nservice: <service>\\nsigner: <signer>\\nvalid_from: <date>'. Pin the payout wallet and a rotated key still verifies.","properties":{"service":{"type":"string"},"signer":{"type":"string"},"valid_from":{"type":"string"},"authority":{"type":"string"},"signature":{"type":"string"}}},"signed_at":{"type":"string"},"signer":{"type":"string"},"algorithm":{"type":"string","enum":["eip191-canonical-json-v1"]},"signature":{"type":"string"}},"required":["request_id","route","input_sha256","signed_at","signer","algorithm","signature"]}},"required":["verdict","grade","one_liner","reasons"]},"example":{"verdict":"green","grade":"SAFE","one_liner":"SAFE: no red flags, $422k liquidity, 3.1 years old","reasons":[{"code":"MUTABLE_METADATA","severity":"info"}],"token":{"chain":"solana","address":"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263","name":"Bonk","symbol":"Bonk"},"market":{"priceUsd":0.0000123,"liquidityUsd":422000,"marketCapUsd":1000000000,"volume24hUsd":350000,"ageSeconds":98000000,"url":"https://dexscreener.com/solana/..."},"sources":["goplus","dexscreener","rugcheck"]}}}},"400":{"description":"Invalid request; nothing is charged"},"402":{"description":"Payment Required"},"503":{"description":"A data source is down; nothing is charged, no verdict"}}}},"/v1/approvals":{"get":{"operationId":"walletApprovals","summary":"Find which open token approvals on a wallet to revoke","tags":["Wallet approvals"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.02"},"protocols":[{"x402":{}},{"mpp":{"method":"evm","intent":"charge","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"mpp":{"method":"tempo","intent":"session","currency":"0x20C000000000000000000000b9537d11c60E8b50"}}],"networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","xrpl:0","algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","stellar:pubnet"],"asset":"USDC","offers":[{"amount":"20000","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","description":"Find which open token approvals on a wallet to revoke","intent":"charge","method":"evm"},{"amount":"20000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Find which open token approvals on a wallet to revoke","intent":"charge","method":"tempo"},{"amount":"20000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Find which open token approvals on a wallet to revoke","intent":"session","method":"tempo","unitType":"request"}]},"parameters":[{"name":"chain","in":"query","required":true,"schema":{"type":"string","enum":["base","ethereum","arbitrum","optimism","polygon","bsc","solana"],"description":"Chain to audit: an EVM chain (ERC-20 allowances) or solana (SPL token delegations)"},"example":"ethereum"},{"name":"address","in":"query","required":true,"schema":{"type":"string","description":"Wallet address (0x... on EVM, base58 on Solana)"},"example":"0x28c6c06298d514db089934071355e5743bf21d60"}],"responses":{"200":{"description":"Audit","content":{"application/json":{"schema":{"type":"object","properties":{"verdict":{"type":"string","enum":["green","orange","red"]},"grade":{"type":"string","enum":["SAFE","CAUTION","RISKY","AVOID"]},"one_liner":{"type":"string"},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["red","orange","info"]},"details":{}},"required":["code","severity"]}},"summary":{"type":"object","description":"approvals, tokens, unlimited, toRevoke (on Solana also tokenAccounts)"},"approvals":{"type":"array","description":"Per allowance: token, spender (address, name, trusted, contract), amount, approvedAt, severity, codes, revoke; on Solana also tokenAccount (where to revoke), program and balance","items":{"type":"object"}},"revokeUrl":{"type":["string","null"],"description":"revoke.cash link (EVM); null on Solana, see revokeHint"},"permanentDelegates":{"type":"array","description":"Solana: Token-2022 tokens held whose mint has a permanent delegate (mint, delegate, tokenAccount); can't be revoked","items":{"type":"object"}},"checkedAt":{"type":"string"},"receipt":{"type":"object","description":"Signature over this whole answer (without receipt.signature), so the verdict can be verified later: EIP-191 personal_sign over canonical JSON (sorted keys, compact, ASCII-escaped). Signer addresses: /.well-known/presign-guard-signer.json; free check: POST /v1/verify.","properties":{"request_id":{"type":"string"},"route":{"type":"string"},"input_sha256":{"type":"string","description":"sha256 of canonical JSON {route, input}: your body (POST) or query parameters (GET)"},"payment":{"type":"object","description":"The payment behind this answer, from your x402 payment payload. EVM: payer + EIP-3009 nonce; find the settlement as AuthorizationUsed(payer, nonce) on the asset contract. Solana: payer + sha256 of the signed transaction you sent.","properties":{"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"pay_to":{"type":"string"},"payer":{"type":"string"},"nonce":{"type":"string"},"transaction_sha256":{"type":"string"},"proof":{"type":"string","enum":["eip3009","svm-transaction"]}}},"cert":{"type":"object","description":"The payout wallet's certificate for this signing key: personal_sign by authority over 'fizzl receipt signer\\nservice: <service>\\nsigner: <signer>\\nvalid_from: <date>'. Pin the payout wallet and a rotated key still verifies.","properties":{"service":{"type":"string"},"signer":{"type":"string"},"valid_from":{"type":"string"},"authority":{"type":"string"},"signature":{"type":"string"}}},"signed_at":{"type":"string"},"signer":{"type":"string"},"algorithm":{"type":"string","enum":["eip191-canonical-json-v1"]},"signature":{"type":"string"}},"required":["request_id","route","input_sha256","signed_at","signer","algorithm","signature"]}},"required":["verdict","grade","one_liner","reasons","approvals"]},"example":{"verdict":"orange","grade":"CAUTION","one_liner":"CAUTION: 3 approvals, 1 unlimited; revoke 1","reasons":[{"code":"UNLIMITED_APPROVAL","severity":"orange","details":{"count":1,"spenders":["0x1111111254eeb25477b68fb85ed929f73a960582"]}},{"code":"STALE_APPROVAL","severity":"info","details":{"count":2,"spenders":["0x000000000022d473030f116ddee9f6b43ac78ba3"]}}],"summary":{"approvals":3,"tokens":2,"unlimited":1,"toRevoke":1},"approvals":[{"token":{"address":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","symbol":"USDC","name":"USD Coin"},"spender":{"address":"0x1111111254eeb25477b68fb85ed929f73a960582","name":"AggregationRouterV5","trusted":false,"contract":true},"amount":"unlimited","unlimited":true,"approvedAt":"2025-03-01T10:00:00.000Z","severity":"orange","codes":[{"code":"UNLIMITED_APPROVAL","severity":"orange"}],"revoke":true}],"revokeUrl":"https://revoke.cash/address/0x...?chainId=8453"}}}},"400":{"description":"Invalid request; nothing is charged"},"402":{"description":"Payment Required"},"503":{"description":"GoPlus is down; nothing is charged, no verdict"}}}},"/v1/screen":{"get":{"operationId":"screenWallet","summary":"Check if a wallet address is on the OFAC sanctions list","tags":["Wallet screening"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.01"},"protocols":[{"x402":{}},{"mpp":{"method":"evm","intent":"charge","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"}},{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"mpp":{"method":"tempo","intent":"session","currency":"0x20C000000000000000000000b9537d11c60E8b50"}}],"networks":["eip155:8453","solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","xrpl:0","algorand:wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=","stellar:pubnet"],"asset":"USDC","offers":[{"amount":"10000","currency":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","description":"Check if a wallet address is on the OFAC sanctions list","intent":"charge","method":"evm"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a wallet address is on the OFAC sanctions list","intent":"charge","method":"tempo"},{"amount":"10000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"Check if a wallet address is on the OFAC sanctions list","intent":"session","method":"tempo","unitType":"request"}]},"parameters":[{"name":"address","in":"query","required":true,"schema":{"type":"string","minLength":20,"maxLength":120,"description":"The wallet address to screen, any chain: EVM (0x...), Solana, Tron, Bitcoin, XRP Ledger, Algorand, or another currency OFAC lists. The format tells the chain."},"example":"TNiq9AXBp9EjUqhDhrwrfvAA8U3GUQZH81"}],"responses":{"200":{"description":"Screen","content":{"application/json":{"schema":{"type":"object","properties":{"verdict":{"type":"string","enum":["green","orange","red"]},"grade":{"type":"string","enum":["SAFE","CAUTION","RISKY","AVOID"]},"one_liner":{"type":"string"},"reasons":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"severity":{"type":"string","enum":["red","orange","info"]},"details":{}},"required":["code","severity"]}},"address":{"type":"object","description":"address, format (evm, solana, tron, bitcoin, xrpl, algorand, other)"},"sanctions":{"type":"object","description":"list (OFAC SDN), listed, matches (uid, name, type, programs, currency), published (the list's date), source"},"sources":{"type":"array","items":{"type":"string"}},"checkedAt":{"type":"string"},"receipt":{"type":"object","description":"Signature over this whole answer (without receipt.signature), so the verdict can be verified later: EIP-191 personal_sign over canonical JSON (sorted keys, compact, ASCII-escaped). Signer addresses: /.well-known/presign-guard-signer.json; free check: POST /v1/verify.","properties":{"request_id":{"type":"string"},"route":{"type":"string"},"input_sha256":{"type":"string","description":"sha256 of canonical JSON {route, input}: your body (POST) or query parameters (GET)"},"payment":{"type":"object","description":"The payment behind this answer, from your x402 payment payload. EVM: payer + EIP-3009 nonce; find the settlement as AuthorizationUsed(payer, nonce) on the asset contract. Solana: payer + sha256 of the signed transaction you sent.","properties":{"network":{"type":"string"},"asset":{"type":"string"},"amount":{"type":"string"},"pay_to":{"type":"string"},"payer":{"type":"string"},"nonce":{"type":"string"},"transaction_sha256":{"type":"string"},"proof":{"type":"string","enum":["eip3009","svm-transaction"]}}},"cert":{"type":"object","description":"The payout wallet's certificate for this signing key: personal_sign by authority over 'fizzl receipt signer\\nservice: <service>\\nsigner: <signer>\\nvalid_from: <date>'. Pin the payout wallet and a rotated key still verifies.","properties":{"service":{"type":"string"},"signer":{"type":"string"},"valid_from":{"type":"string"},"authority":{"type":"string"},"signature":{"type":"string"}}},"signed_at":{"type":"string"},"signer":{"type":"string"},"algorithm":{"type":"string","enum":["eip191-canonical-json-v1"]},"signature":{"type":"string"}},"required":["request_id","route","input_sha256","signed_at","signer","algorithm","signature"]}},"required":["verdict","grade","one_liner","reasons","sanctions"]},"example":{"verdict":"red","grade":"AVOID","one_liner":"AVOID: on the OFAC SDN list (BANK MARKAZI JOMHOURI ISLAMI IRAN)","reasons":[{"code":"SANCTIONED_ADDRESS","severity":"red","details":{"list":"OFAC SDN","matches":[{"uid":4632,"name":"BANK MARKAZI JOMHOURI ISLAMI IRAN","type":"Entity","programs":["IRAN","IFSR","IRGC","SDGT"],"currency":"TRX"}],"published":"2026-10-09"}}],"address":{"address":"TNiq9AXBp9EjUqhDhrwrfvAA8U3GUQZH81","format":"tron"},"sanctions":{"list":"OFAC SDN","listed":true,"matches":[{"uid":4632,"name":"BANK MARKAZI JOMHOURI ISLAMI IRAN","type":"Entity","programs":["IRAN","IFSR","IRGC","SDGT"],"currency":"TRX"}],"published":"2026-10-09","source":"ofac-sdn"},"sources":["ofac-sdn"]}}}},"400":{"description":"Invalid request; nothing is charged"},"402":{"description":"Payment Required"},"503":{"description":"The sanctions list is not available; nothing is charged, no verdict"}}}},"/v1/sanctions":{"get":{"operationId":"sanctionsList","summary":"Get every OFAC-listed crypto address, free (open data)","tags":["Wallet screening"],"security":[],"responses":{"200":{"description":"list, source, published, checkedAt, count, addresses: [{ address, entries: [{ uid, name, type, programs, currency }], tokenAccounts (Solana addresses only): { USDC, USDT } }]"},"503":{"description":"The list is not loaded yet; try again in a minute"}}}},"/v1/credits":{"get":{"operationId":"credits","security":[],"summary":"Free: pack prices, credit cost per call, and your balance with the x-credit-key header","responses":{"200":{"description":"Prices and balance"},"404":{"description":"Unknown key"}}}},"/v1/credits/100":{"get":{"operationId":"buyCredits100","summary":"Buy 100 prepaid credits ($0.80); returns a credit key for the x-credit-key header","x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.80"},"protocols":[{"x402":{}}],"asset":"USDC"},"responses":{"200":{"description":"credit_key, credits, expires_at"},"402":{"description":"Payment Required"}}}},"/v1/credits/1000":{"get":{"operationId":"buyCredits1000","summary":"Buy 1000 prepaid credits ($7.00); returns a credit key for the x-credit-key header","x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"7.00"},"protocols":[{"x402":{}}],"asset":"USDC"},"responses":{"200":{"description":"credit_key, credits, expires_at"},"402":{"description":"Payment Required"}}}}},"x-agentcash-provenance":{"ownershipProofs":["0x6392852e7aeda7d513712b56663040d0f297727c058e28df5c084abf90228d486cfe9c5816faee14625c55e9827f9c8cce630d130d01fab38d0c33193bbc3ec91c"]},"x-service-info":{"categories":["security","payments","blockchain"],"docs":{"homepage":"https://presign-guard.fizzl.eu","apiReference":"https://presign-guard.fizzl.eu/openapi.json","llms":"https://presign-guard.fizzl.eu/skill.md"}}}