The three quote shapes
A quote answers in one of three shapes, one per venue. How to tell them apart and read each.
POST /v1/trades/quote answers { "quote": { ... } }. The object has one of three shapes, because the venues
differ. They are told apart by two flags, not by a kind field.
| Venue | How to tell | Output field | Minimum field |
|---|---|---|---|
| Curve | no graduated, no collectible | expectedOut | minOut |
| Market (a launch past the curve) | graduated: true | expectedOut | minOut |
| Pool (a tradable collectible) | collectible: true, graduated: false | estimatedAmountOut | minAmountOut |
A pool quote has no expectedOut. A client that reads the curve's field names off a pool quote shows "you receive
0" beside a good quote. Branch on the flags first.
type AnyQuote = Record<string, any>;
function receive(q: AnyQuote): { out: string; min: string } {
if (q.collectible === true) return { out: q.estimatedAmountOut, min: q.minAmountOut };
return { out: q.expectedOut, min: q.minOut };
}Curve
The curve quote carries what the program will move:
componentTargets: the deposits, per component, in recipe order.componentFees: the fee, per component.componentFunding(only when you sent awallet): per component,required,heldandshortfall. A component withshortfall: "0"needs no swap.route(only when you sent awalletand the deployment has a pool table):solIn,legs,venues,needsAccountSetup,transactionsand anote.routeabsent means "not evaluated". It does not mean no route exists: that is a presentroutewith emptylegs.expectedOutandminOut. For a buy they are launch tokens, in base units. For a sellexpectedOutis in DNA units, the internal quote unit, and must never be printed as SOL. The SOL a sell returns isroute.solIn, and it is a floor.dnaUnitsNetis net of the fee on a buy and gross of it on a sell. A sell also carriesdnaUnitsGross, the same value under the name that is true of it.clamped: truemeans the buy was cut to what remains on the curve.budgetSolInis then the real cost of anexactInSolbuy.completesCurve: truemeans this buy, filled as quoted, completes the curve.networkCostandtradeSettingsappear where the chain has tips or priced fees.
minOut is the floor the program enforces. Below it the transaction aborts.
Market
A launch past the curve trades through its pools. The quote describes the route:
routes: every spoke this size could have gone through alone, best first, withexpectedOut,spreadBps,worstHopImpactBpsandusable.hops: the swaps in order, each withlabel,inputMint,outputMint,amountInandamountOut.hopDetailcarries the same swaps with the pool, the venue, the impact and the fee.via: the component the route enters through.split,hubBalanceandrouteNoteappear when a route is shared between pools, or a better one did not fit one transaction.
Pool
A tradable collectible trades on its own pool, in one hop:
pool,amountIn,estimatedAmountOut,minAmountOut,priceImpactBps,via.feeBpsandfeeAmount: the pool's fee rate and this trade's fee, in base units ofamountIn's mint.
Fields on all three
| Field | Meaning |
|---|---|
quoteId | What build takes. Not usable from a preview quote. |
launch | The launch address. |
direction, amountIn | What you asked. |
priceImpactBps | End to end, in basis points. Zero when the trade beats the reference price. |
fairOut, expectedIn, hopCount, hopDetail | Present on current servers; optional on the wire. |
The reference lists every field with its type: Quote a trade.
Test against captures
These shapes are pinned in the API's own test suite against responses captured from the live API, not against mocks written in the shape the author expected. Do the same: keep a capture of each shape and run your parser over it.