Quotes and pricing
GET /v2/quote prices one direction and size without creating an order. Use it on your confirmation screen: “you send X, you receive Y”. It is a required step, because the price exists nowhere else. The API never invents one.
Price from either side
Section titled “Price from either side”mode |
You send | You get back |
|---|---|---|
exact_input (default) |
srcAmount: what the user spends |
receive.amount: what the user gets |
exact_output |
outcomeAmount: what the user should receive |
spend.amount: the smallest deposit that gets there |
Both amounts come back either way, so you never invert a rate yourself. Send only the amount that mode names. Both, neither, or the other one is a 400.
curl -s "https://api.hyperstream.dev/v2/quote?fromChainId=42161&from=0xaf88d065e77c8cC2239327C5EDb3A432268e5831&toChainId=1&to=0xdAC17F958D2ee523a2206206994597C13D831ec7&srcAmount=100000000" \ -H "X-API-Key: $KHALANI_API_KEY"What to show the user
Section titled “What to show the user”Show spend.amount and receive.amount using their respective decimals. They reflect the token fees; source-chain transaction gas and the native-token relay fee in depositTx.value are additional. details.protocolFee is Khalani’s part of the fees and does not include your commission. See Fees and commission.
details.intentOutcomeRate is the solver’s rate for the amount left after fees, not the all-in rate for the deposit. Don’t display it.
What a quote guarantees
Section titled “What a quote guarantees”A 200 means the size is fillable right now. Solvers name a minimum and a maximum on every quote, and the API refuses sizes outside them rather than pricing something it would not fill. On exact_output there is no minimum. A small target returns a larger spend.amount instead.
Prices move, and a quote reserves nothing. Two quotes seconds apart can differ.
The rate per unit is guaranteed; the total is not. Orders can fill partially. If an order for 1,000 fills 600, the user receives 600’s worth at the quoted rate and is refunded the rest, less the flat fee and the percentage fees on the filled 600. So exact_output means “if the order fills completely, the user receives at least this amount”. When a shortfall is unacceptable, such as paying an invoice of a fixed amount, read the order’s settledOutcome and top up.
exact_output can deliver slightly more, never less. receive.amount comes back at or above outcomeAmount. The excess is at most one source base unit’s worth, because a deposit moves in whole source base units.
The build object
Section titled “The build object”build is the /v2/build request, already assembled. Send it back unchanged with the depositor’s address added:
await post("/v2/build", { ...quote.build, depositor });build.terms is Khalani’s signed attestation of this quote. It pins the build to exactly the numbers you showed the user, and it is valid for five minutes, until build.terms.expiresAt (Unix seconds). From that second on the build returns 409 and you quote again. A build with any field of build changed returns 400.
A quote is not used up by a build. You can build the same quote more than once within its five minutes, and each build creates a separate order.
Size limits
Section titled “Size limits”Too small returns 400 with detail.minSrcAmount. Too large returns 409 with detail.maxSrcAmount (exact_input) or detail.maxOutcomeAmount (exact_output). Re-quote at the returned figure.
- The returned figures are adjusted so that re-quoting at them works. The limits can move between calls, so a retry can still fail. If it does, follow the new figure.
- A too-small refusal can mean the deposit does not exceed the flat fee, solvers will not fill that little, or the output would round below one destination base unit. The flat-fee check runs first, before solvers are asked, so its
minSrcAmountclears only the flat fee: quote again and follow the next figure. The other two refusals return aminSrcAmountthat clears all three. - There is no minimum in
GET /v2/params. Only a quote can tell you.
As of 19 October 2026, quoting 1,000 base units (0.001 USDC) from Arbitrum USDC to Ethereum USDT returned:
{ "error": "Deposit is at or below the flat fee, so nothing would be published", "detail": { "minSrcAmount": "99899" } }Timing
Section titled “Timing”The quote asks solvers for a price and waits up to five seconds. The solver-minimum and one-base-unit refusals make a second pricing call to compute the minimum, so those 400s can take about twice as long as a 200.
See the GET /v2/quote reference for every field and status.