{"openapi":"3.1.0","info":{"title":"usevig","version":"0.1.0","description":"Agentic stablecoin payments through CREATE2 checkout addresses. The payer sends an ordinary transfer, usevig watches the chain, and the merchant signs collection. usevig holds no funds or gas money. Metered per verified transaction.","contact":{"email":"founders@usevig.com"}},"servers":[{"url":"https://usevig.com"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"schemas":{"Error":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}},"paths":{"/health":{"get":{"summary":"Liveness","security":[],"responses":{"200":{"description":"Healthy."}}}},"/v1/config":{"get":{"summary":"Current checkout networks, tokens, finality, and gas responsibilities","security":[],"responses":{"200":{"description":"Config."}}}},"/v1/merchants":{"post":{"summary":"Create a free Base Sepolia test merchant","security":[],"responses":{"201":{"description":"Created."},"400":{"description":"Invalid network or payout address.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"402":{"description":"A mainnet account needs a plan purchase through POST /v1/signup.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/me":{"get":{"summary":"Tier, usage and settings","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account."},"401":{"description":"Bad key.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}},"patch":{"summary":"Update account settings (partial)","description":"Updates any subset of accepted, payout_address, webhook_url, finality and name. Fields you omit are left unchanged; they are never nulled. Every value is checked with the same validator account creation uses. POST is accepted as an alias for clients that cannot send PATCH.\n\nChanging payout_address affects LATER checkouts only. Receiving addresses already quoted were derived from the previous payout address and cannot be re-pointed. Funds at those addresses still collect there. Nothing is moved or lost.\n\nA stored `accepted` list becomes the default for checkouts created without an explicit accept. A per-checkout accept still wins. Every entry must be permitted by your tier: a test-tier account cannot store a mainnet default.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"description":"Default {network, token} pairs, or null to clear and fall back to every token on your own network.","oneOf":[{"type":"array","items":{"type":"object","properties":{"network":{"type":"string"},"token":{"type":"string"}}}},{"type":"null"}]},"payout_address":{"type":"string"},"webhook_url":{"type":"string","nullable":true},"finality":{"type":"string","enum":["instant","confirmed","safe","finalized"]},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"The updated account, in the same shape GET returns."},"400":{"description":"Invalid field, or an empty body.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"401":{"description":"Bad key.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"403":{"description":"Your tier does not permit one of the requested networks.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/pay/demo":{"get":{"summary":"Create a $0.01 Base Sepolia CREATE2 checkout and redirect to it","security":[],"responses":{"302":{"description":"Redirect to /pay/c/chk_...."},"429":{"description":"Demo rate limit reached.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/signup":{"post":{"summary":"Buy a plan and create a mainnet account","description":"Fully self-serve: no credentials, no approval, no human. Returns a real usevig checkout you pay in stablecoins on any supported mainnet. The account is created immediately in plan_status 'pending' and activates automatically once the payment confirms — poll status_url for the api_key. An underpayment does NOT activate it.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan","payout_address"],"properties":{"plan":{"type":"string","enum":["trial","starter","scale"]},"payout_address":{"type":"string","description":"0x address you control. Collected checkout funds can only reach it."},"network":{"type":"string","description":"Which mainnet your ACCOUNT lives on. Defaults to base. Independent of the chain you pay with."},"pay_with":{"type":"array","description":"Optional {network, token} pairs you want to pay with. Defaults to every stablecoin on every supported mainnet.","items":{"type":"object","properties":{"network":{"type":"string"},"token":{"type":"string"}}}},"name":{"type":"string"},"webhook_url":{"type":"string"}}}}}},"responses":{"201":{"description":"Pending account plus the checkout that activates it."},"400":{"description":"Unknown plan, or an invalid/own payout address.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/signup/{purchase_id}":{"get":{"summary":"Poll a signup or renewal","description":"Public, no API key — an agent must be able to collect the key it just paid for. Returns api_key exactly ONCE, on the first read after activation.","security":[],"parameters":[{"name":"purchase_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Purchase state, plan state, and the api_key once paid."},"404":{"description":"No such purchase.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/plan":{"get":{"summary":"Current plan","description":"Tier, status, expiry, and explicitly whether you can create mainnet checkouts and collect funds. can_collect_funds is always true — an expired plan never strands money already paid to you.","responses":{"200":{"description":"Plan state."}}}},"/v1/redeem":{"post":{"summary":"Redeem a coupon code","description":"Applies a code to the authenticated account, activating the plan it grants with no payment. Never creates a checkout. Codes are normalised (trimmed and uppercased), work once per account, and extend an existing plan rather than replacing it. Unknown and malformed codes return the same error so responses cannot be used to discover which codes exist.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code"],"properties":{"code":{"type":"string","example":"VIG-XXXX-XXXX-XXXX"}}}}}},"responses":{"200":{"description":"Redeemed; the plan is active."},"404":{"description":"Unknown or malformed code.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"409":{"description":"Already redeemed by this account, exhausted, or expired.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"429":{"description":"Too many redemption attempts.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/plan/renew":{"post":{"summary":"Renew or change tier","description":"Returns another checkout. Renewing early extends from your current expiry rather than from today, and does not rotate your api_key.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["trial","starter","scale"]},"pay_with":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"201":{"description":"Renewal checkout."},"400":{"description":"Nothing to renew on a free network.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/checkouts":{"post":{"summary":"Create a plain-transfer checkout","description":"Price in USD and get a unique CREATE2 receiving address per network and token. The payer sends an ordinary ERC-20 transfer. usevig holds no private key for the returned addresses.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount_usd"],"properties":{"amount_usd":{"type":"number","example":12.5},"accept":{"type":"array","description":"Optional {network, token} pairs the payer may choose from. Networks: ethereum, base, arbitrum, optimism, polygon, base-sepolia. Tokens vary per network — see GET /v1/config. Defaults to every token supported on the key's own network.","items":{"type":"object","properties":{"network":{"type":"string"},"token":{"type":"string"}}}},"finality":{"type":"string","enum":["instant","confirmed","safe","finalized"],"description":"Which level marks the checkout paid. Defaults to confirmed. Webhooks fire at every level regardless of this choice."},"resource":{"type":"string"},"ttl_seconds":{"type":"integer"}}}}}},"responses":{"201":{"description":"Checkout created, with checkout_url and options[]."},"400":{"description":"Invalid amount, finality, or accepted token.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}},"get":{"summary":"List checkouts","parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"List of checkouts."}}}},"/v1/checkouts/{id}":{"get":{"summary":"Read a checkout","description":"Status, the finality level reached, observed transfers, and an exact shortfall if the payer underpaid.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checkout."},"404":{"description":"Unknown checkout.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/collect/quote":{"get":{"summary":"Build an UNSIGNED sweep transaction","description":"Returns {to, data, value} that sweeps your received funds to your payout address. usevig cannot sign or broadcast it — you sign it and pay your own gas. Multiple checkouts are batched into one Multicall3 call so you sign once; this saves signatures, not gas (measured saving is ~1.3%).","parameters":[{"name":"network","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Unsigned transaction plus unswept detail."},"401":{"description":"Missing or invalid API key.","content":{"application/json":{"schema":{"type":"object","required":["error","fix"],"properties":{"error":{"type":"string","description":"Stable machine-readable code."},"fix":{"type":"string","description":"Plain-language instruction for the caller."}}}}}}}}},"/v1/balance":{"get":{"summary":"Uncollected funds","description":"Amount, address count and chains for funds paid to you but not yet swept. These sit in contract addresses whose only possible destination is your payout address; usevig cannot redirect them.","responses":{"200":{"description":"Uncollected balance summary."}}}},"/pay/c/{checkout_id}":{"get":{"summary":"Hosted checkout page for a human","description":"Public, no API key. Shows the payer a coin/chain picker, the receiving address, the exact amount and a QR code. Returns HTML.","security":[],"parameters":[{"name":"checkout_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checkout page."},"404":{"description":"No such checkout."}}}},"/mcp":{"post":{"summary":"MCP JSON-RPC 2.0 endpoint","security":[],"responses":{"200":{"description":"JSON-RPC result."}}}}}}