# usevig > Drop-in HTTP 402 payments for AI agents. Your keys, your money, we run the plumbing. > Non-custodial: funds move directly payer -> merchant via EIP-3009 transferWithAuthorization. > usevig is a relayer. We never hold, escrow, or route your funds, and we never take a cut of value. ## Try it right now with zero credentials 1. Create a free Base Sepolia merchant. No signup, no email, no funds. curl -X POST https://usevig.com/v1/merchants \ -H 'Content-Type: application/json' \ -d '{"network":"base-sepolia","payout_address":"0xYourAddress"}' -> {"merchant_id","api_key","webhook_secret","network":"base-sepolia",...} The test tier runs on Base Sepolia and uses the SAME code path as mainnet: real EIP-712 signatures, a real on-chain relay, real confirmations. Only the network differs, and testnet gas is worthless. Nothing is mocked. Get testnet USDC and ETH from https://www.alchemy.com/faucets/base-sepolia. 2. Create a charge. Amount is an integer string in the asset's smallest unit (USDC has 6 decimals, so "10000" = $0.01). curl -X POST https://usevig.com/v1/payments \ -H "Authorization: Bearer $VIG_KEY" -H 'Content-Type: application/json' \ -d '{"amount":"10000","resource":"GET /premium"}' -> HTTP 402 with a complete EIP-712 challenge you can sign as-is. 3. Sign the challenge's eip712 payload with your wallet, then settle: curl -X POST https://usevig.com/v1/payments/$PAYMENT_ID/settle \ -H 'Content-Type: application/json' \ -d '{"signature":"0x...","from":"0xYourWallet"}' We verify the signature and relay transferWithAuthorization on-chain, then poll to your configured confirmation depth. This is identical on testnet and mainnet. ## Endpoints GET /v1/config chain, asset, EIP-712 domain/types, pricing POST /v1/merchants create merchant (base-sepolia self-serve) GET /v1/me tier, usage this period, confirmations POST /v1/payments create a charge -> HTTP 402 challenge POST /v1/payments/:id/settle submit signature -> verify + relay GET /v1/payments/:id status, tx hash, confirmations GET /v1/payments list payments (?limit=&cursor=) POST /mcp MCP server (JSON-RPC 2.0, streamable http) GET /health liveness GET /openapi.json machine-readable spec ## Signing details — the EIP-712 domain differs per network The token's name() feeds the EIP-712 domain, and it is NOT the same on both networks. Using the wrong one produces a domain the token will reject, so read these from GET /v1/config rather than hardcoding them. base chainId: 8453 asset: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (USDC, 6 decimals) name(): "USD Coin" <- differs per network domain: {"name":"USD Coin","version":"2","chainId":8453,"verifyingContract":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"} separator:0x02fa7265e7c5d81118673727957699e4d68f74cd74b7db77da710fe8a2c7834f explorer: https://basescan.org access: PAID ONLY — no free mainnet allowance base-sepolia chainId: 84532 asset: 0x036CbD53842c5426634e7929541eC2318f3dCF7e (USDC, 6 decimals) name(): "USDC" <- differs per network domain: {"name":"USDC","version":"2","chainId":84532,"verifyingContract":"0x036CbD53842c5426634e7929541eC2318f3dCF7e"} separator:0x71f17a3b2ff373b803d70a5a07c046c1a2bc8e89c09ef722fcb047abe94c9818 explorer: https://sepolia.basescan.org access: free, self-serve primaryType: TransferWithAuthorization types: {"TransferWithAuthorization":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"validAfter","type":"uint256"},{"name":"validBefore","type":"uint256"},{"name":"nonce","type":"bytes32"}]} Both separators above match the on-chain DOMAIN_SEPARATOR() of their token and are asserted in our test suite. We settle with transferWithAuthorization (not receiveWithAuthorization) so that usevig submits the transaction and pays the gas, not you and not the merchant. ## Things worth knowing - Every 4xx body has a "fix" field in plain language saying what to do next. Read it. - Nonces are single-use. Replay is rejected twice: a D1 uniqueness constraint on (token, payer, nonce) and an on-chain authorizationState() check. - Authorizations outside validAfter/validBefore are rejected against block time. - Send an Idempotency-Key on POSTs. The same key with the same body replays the original response and never submits a second on-chain relay. - Payments are not final at 1 confirmation. Status moves challenged -> verifying -> pending -> confirmed -> final. Confirmation depth is per-merchant. A vanished transaction is demoted to "reorged". - Smart-account agents are supported: 65-byte ECDSA and EIP-1271 contract signatures both verify. ## Webhooks Signed with HMAC-SHA-256 as 'X-Vig-Signature: t=,v1=' over ".". Verify with a timing-safe compare and reject timestamps older than 300s. Every event has an id in 'X-Vig-Event-Id' — dedupe on it. Retries use exponential backoff and dead-letter after 8 attempts. ## Pricing — metered on transactions verified, never on value transferred test Free — Base Sepolia testnet, self-serve, real on-chain settlement starter $49/mo — up to 11,000 verified mainnet transactions scale $299/mo — up to 72,000 verified mainnet transactions enterprise Custom — self-hosted relayer, you supply the gas key Test tier is Base Sepolia and free. Mainnet is paid only — there is no free mainnet transaction allowance, because every mainnet relay costs us real gas (about $0.001032 all-in, L2 execution plus the OP-Stack L1 data fee). A merchant moving $1M pays exactly the same as one moving $10k at the same transaction count. Each account has TWO independent ceilings, and whichever is reached first stops further relays: included_transactions what you bought (the "up to" figure) relay_gas_budget_usd half the plan price, per period The gas budget is what guarantees our margin, so it is the real limit when gas is expensive. At today's gas price your full included volume fits inside the budget with room to spare; the budget only binds first if ETH roughly doubles. That is why the plans say "up to" rather than promising a flat number we might not be able to deliver. Exceeding either returns 402 with a distinct code: included_transactions_exhausted you used your included volume gas_budget_exhausted the period's relay-gas budget ran out GET /v1/me reports both counters, how much of each remains, and which one is currently binding. Enterprise merchants supply their own relayer key, pay their own gas, and are not subject to the budget cap. ETH/USD for gas accounting comes from the Chainlink feed on the network being relayed (cached, with staleness and sanity guards). A price lookup can never fail a payment — it is accounting, not settlement. GET /v1/config reports the resolved price, its source, and its age. ## Responsibilities usevig verifies signatures and relays transactions. Refunds, chargebacks and disputes are between the merchant and their customer — usevig cannot reverse a settled on-chain transfer and does not mediate disputes. Merchants hold their own keys; we never custody merchant keys or customer funds. ## Contact founders@usevig.com