The full payment flow
1
Agent requests a paid endpoint
Your agent makes a standard HTTP request to a seller’s API endpoint — for example,
GET https://api.example.com/premium/data. No special headers are needed at this point.2
Seller returns HTTP 402 with a payment challenge
The seller’s API responds with The Mandate SDK parses this challenge automatically when you use
HTTP 402 Payment Required and an X-Payment-Challenge header. The header value is a base64url-encoded JSON object that describes what the seller requires:fetchWithPayment().3
SDK calls POST /v1/policy/evaluate
Before generating any proof, the SDK submits the payment request to Mandate’s policy engine. Mandate checks the request against 9 rules — verifying your agent’s status, mandate validity, merchant allowlist, category restrictions, per-transaction limit, and total budget.If the payment is within policy, Mandate returns
{ "decision": "approved" }. If any check fails, it returns { "decision": "denied" } with a reason_code and the SDK throws a PolicyDeniedError. See Policy engine for the full list of checks.4
SDK calls POST /v1/payments/proof
Once the policy engine approves the request, the SDK requests a signed payment proof from Mandate. In sandbox mode, this proof is an HMAC-SHA256 signature over the payment parameters. In production, this will be an on-chain payment on Base.Mandate returns a signed proof object that is valid for 5 minutes and can only be used once.
5
Agent retries the request with X-Payment-Proof
The SDK retries the original request, this time attaching the signed proof in the
X-Payment-Proof header. The header value is the base64url-encoded proof object.6
Seller calls POST /v1/payments/verify
The seller’s middleware receives the request and calls Mandate to verify the proof. Mandate checks the timestamp (within a 5-minute window), validates the HMAC signature, confirms the amount and currency match, and ensures the nonce has not been used before. If valid, Mandate charges the mandate and records the transaction.The seller receives
{ "verified": true } and your mandate’s spent_total is incremented atomically.7
Seller returns 200 with the requested resource
With proof verified, the seller fulfils the original request and returns
HTTP 200 with the data your agent requested. The full round-trip is complete.Sandbox vs. production behaviorIn sandbox mode (API keys prefixed
ky_sand_), payment proofs are HMAC-SHA256 signatures generated by Mandate’s signing key. No real money moves. In production, proofs will be on-chain USDC payments on Base mainnet — the verification step will confirm the on-chain transaction instead of the HMAC signature. The SDK and middleware interfaces remain identical between environments; only the key prefix changes.
