Before your agent pays: a preflight checklist for x402
In a typical x402 exchange, a server answers 402 Payment Required, the client chooses a payment option, and it retries with a signed authorization. Verification and settlement are part of the payment flow; deciding whether to spend is your agent’s job. Here are ten checks worth considering before it signs.
1. The asset is the token you think it is
A challenge names an asset by contract address and a network by CAIP-2 id (for example eip155:8453 for Base). Compare the pair against an allowlist of the stablecoin contracts you actually intend to spend. USDC on Base is 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913. A lookalike token on the same chain should be a hard block, not a warning.
2. The amount is in units you understand
Amounts are atomic units. In v2 the field is amount; in v1 it is maxAmountRequired. USDC has 6 decimals, so 10000 is one cent. Parse the amount as a non-negative integer and compare using exact arithmetic. Reject unsupported assets, networks or payment schemes instead of guessing their value.
3. The price fits a per-payment cap
Set a maximum per payment and a lower threshold that triggers a human hold. Choose limits that fit the workload, then require review when a quote exceeds them. A price alone does not establish whether a service is trustworthy.
4. The day's spend fits a budget
A per-payment cap doesn't stop a loop that pays one cent ten thousand times. Track spend per agent per day, and block once the next payment would exceed the budget. Reserve concurrent payments against a shared ledger before signing; one process’s local counter does not enforce a fleet-wide budget.
5. Screen the payee and check the data’s age
The U.S. Treasury’s OFAC SDN list includes cryptocurrency addresses. Screen payTo against a current copy and route matches for appropriate review. OFAC says its listed digital currency addresses are not exhaustive, so a no-match result is not clearance. Applicable obligations depend on the parties and circumstances; an address lookup alone is not a sanctions compliance program.
6. The payee didn't just change
Compare payTo with the value your client previously approved for that endpoint. A change can be a legitimate rotation or a warning sign; hold it for review rather than assuming either. This comparison requires caller-maintained history. The currently deployed SpendPreflight API does not track payee-change history.
7. The domain is what you called, and it isn't brand new
Bind the challenge’s resource to the URL your client actually requested, including the expected origin and path. Domain registration age can inform review, but a new domain is not proof of fraud and an old one is not proof of safety. Treat unavailable age data as unknown. The caller must enforce the requested-URL binding.
8. Allowlists for vendors you trust, holds for everything else
An allowlist of domains and payee wallets can send unfamiliar vendors to review. Membership should not bypass other checks: budget limits, supported assets, sanctions matches and explicit blocks still apply.
9. Every decision leaves a receipt
Keep a receipt with the chosen payment option, decision, reasons, timestamp and a reference or hash for the challenge. Minimize sensitive data and choose a retention period. SpendPreflight returns a decision receipt; your application stores it. We do not retain caller request bodies or provide a stored receipt-history service.
10. Fail safe, not open
If a required check cannot run, default to hold. Set explicit freshness and unknown-data policies in your application, inspect the returned signals, and stop when those policies are not met. An API decision is only one input to your client’s final authorization.
Automating parts of the checklist
SpendPreflight’s live POST https://api.spendpreflight.com/v1/preflight endpoint accepts a 402 challenge or cart plus rules and returns allow, hold or block with reasons and a receipt. It supports amount and network rules, caller-supplied daily-spend context, OFAC screening and domain signals. A paid call costs $0.02 over x402.
Your client still owns payment authorization, the requested-URL binding, payee-change history, concurrency-safe budget accounting, required-data freshness policies and receipt storage. The API does not sign or settle your proposed merchant payment.
To try it without payment, explicitly request /v1/preflight?trial=1. There are three free trial calls per IP per UTC day, shared across HTTP and MCP; exhausted trials return payment-required rather than automatically paying. See the live default rules and OpenAPI schema before integrating.
For TypeScript, the MIT-licensed spendpreflight client guard provides local rules and optional remote screening. Follow its published README and account for its process-local budget scope. AI assistants can also call the live tools at https://api.spendpreflight.com/mcp.
Screening is informational. It isn't legal advice or a compliance certification, so verify any match before acting. How to verify our claims · OpenAPI