Production base URL is currently
https://quiet-bloodhound-531.convex.site. If you’re integrating against a vanity domain (e.g. https://api.o1.exchange/dex), substitute that throughout.Prerequisites
API key
See Authentication to request one.
Base RPC URL
Any Base mainnet RPC works. We use
viem defaults below.Wallet with USDC
Plus a small ETH balance to pay gas (and approve the router if this is your first swap).
1. Set up your client
2. Get a quote
- Request
- Response
Endpoint:
POST {API_URL}/quoteroutePlan.expectedAmountOut— the price you quoteroutePlan.minAmountOut— the worst-case fill after slippageroutePlan.routes[].legs[].dex— which venues are involvedexpiresAt— quote validity window (about 10 seconds; see Quote freshness)
3. Approve the router (first swap only)
Skip this step entirely if
tokenIn is native ETH, or if you’re using an EIP-2612 permit (see POST /submit → permit).4. Build the transaction
- Request
- Response
Endpoint:
POST {API_URL}/submit5. Sign and send
publicClient.waitForTransactionReceipt({ hash: txHash }) and the swap is complete.
Full example, end to end
Complete TypeScript script
Complete TypeScript script
What’s next
Two-step vs one-step
When to use
/quote + /submit vs /execute.ERC-20 approvals
Approve patterns, including one-tx permit-enabled swaps.
Native ETH
Sell ETH directly without wrapping, or receive ETH instead of WETH.
Quote freshness
How to keep the displayed price live in your UI.
