1
Quote
GET /quote?inputMint=…&outputMint=…&amount=…&slippageBps=50 answers the route, the amounts and otherAmountThreshold. Every quote is checked to be buildable before it is served.2
Build
POST /swap-instructions with userPublicKey and the quote (quoteResponse) answers the instructions; add "serialize": true for an unsigned transaction.3
Sign and send
Sign the v1 transaction with the user’s key and send it before its blockhash expires (about a minute).
Three ways to name the route at build time
The build takes the route in one of three forms, in this order of precedence:
With a quote or a ticket, any
inputMint, outputMint (and with a ticket, amount) you also send must match it, or the build answers 400 quote_mismatch / route_ticket_mismatch. If a pinned route crosses a venue the router has since stopped serving, the build answers 409 venue_red: quote again.
routeTicket is not authentication. It is the quote, readable by anyone, with an HMAC so it cannot be altered. A router without ROUTER_TICKET_SECRET puts no ticket on its quotes and answers 400 invalid_route_ticket to one.ExactIn and ExactOut
swapMode is ExactIn (default) or ExactOut.
How an ExactOut is executed depends on the route:
- One hop on a venue with an exact-output instruction (
onchainExactOutin/venues): the output is pinned and the input is at mostotherAmountThreshold. - Anything else (several hops, or a venue without that instruction): the route is built as an exact-in that spends the slippage cap (
otherAmountThreshold) with a minimum output equal to the requested amount. The user pays the cap, notinAmount, and any output above the requested amount stays with the user.
shape (exact_out or token_exact_in) and gives the bounds as minReturn and maxAmountIn.
Slippage
slippageBpsdefaults to 50 (0.5%) and cannot exceed 10000.- A
slippageBpsin the build body replaces the quote’s (or the ticket’s). Send it only on purpose. - Your deploy’s admin can cap slippage per venue on chain. A lower cap makes a route revert beyond it, even inside the slippage you asked for.
Choosing venues
Lists are comma-separated in the query string, or JSON arrays in a
POST /quote body. Venues the router’s price checks currently hold out are removed from every quote automatically; GET /ready lists them in red_pass.
Split routes
allowSplit=true lets the router split an ExactIn across two routes in one transaction, when the split beats the best single route by at least 1 bps and still fits the transaction. In the quote, routePlan lists route A’s steps then route B’s; the first step of each carries its share in percent (rounded) and bps (exact).
Splits are not served for ExactOut or with a platform fee.
Wrapping SOL
wrapAndUnwrapSol (alias unwrapSol) defaults to true:
- SOL in: the build moves the lamports into the user’s wrapped-SOL account (creating it) and closes it after the swap.
- SOL out: the build unwraps by closing the user’s wrapped-SOL account, except when the output goes to another wallet (
destinationTokenAccount), which receives wrapped SOL.
false, the swap spends from and pays into the user’s wrapped-SOL token account and nothing is wrapped or closed.
Sending the output elsewhere
destinationTokenAccount (alias recipient) is the wallet that receives the output, not a token account: the output lands in that wallet’s associated token account, created if missing. A token account there is refused with 400 bad_recipient (it would have received into a nested account the owner cannot see).