Build a signable/sendable plan for a swap

No credential is required; wallet is mandatory and declares the EVM address that will sign. Two modes: pass quoteId from a prior POST /quote to build exactly that route; omit it and pass the intent fields (chainId, tokenIn, tokenOut, amount|amountRaw) to quote and build the best route in one round trip. When it picks the route itself, a route with GAIN comes first; if the first round has none, it re-quotes up to 3 rounds total (1.5 s apart) before falling back to the best route without gain, the same rule as Invoice. When the first round has no gain this costs up to two extra quote rounds plus 3 s of pauses, about 7-8 s more measured on Base on 02/10/2026; with gain in the first round it costs nothing. Always re-quotes fresh before building — if the market moved, quote.amountOut reflects the fresh price, not the one from POST /quote.

post/swap

Request

  • Base URL: https://swap.vurto.cc/v1
  • URL: https://swap.vurto.cc/v1/swap
  • Auth: none required

Request body

walletstring required

EVM address that will sign the plan.

quoteIdstring
chainIdinteger
tokenInstring
tokenOutstring
amountstring
amountRawstring
slippageBpsinteger
maxSlippageBpsinteger

Optional ceiling, 0-10000, for every future POST /swap/{buildId}/refresh of this build. Once set it never loosens: a refresh asking for a laxer value is clamped back down to this.

receiverstring

Optional address to deliver the output to, if different from the signing wallet. Ignored when quoteId is set — the receiver from that quote is used. Only honored by providers with supportsReceiver: true.

calldataSemSimulacaoboolean

Opt-in: return the swap calldata even when the final simulation has not run, for DIRECT-POOL routes only. For an integrator that simulates on its own before listing the route, which is how aggregator adapters work. The default stays off and the general rule holds: a simulation that did not pass comes with no transaction. In a direct route the calldata is built by us from the pool we read, so what is missing is the proof of effect, not the provenance; relaying an aggregator calldata unsimulated stays refused. simulation.status is returned untouched, so the response never lies about what was checked.

Response

OK

buildIdstring uuid

Identity of this specific build. Use in POST /swap/{buildId}/refresh.

buildHashstring

sha256 canonical hash of chainId + wallet + destination + calldata + value. Recompute and compare before signing if you don't trust the transport.

walletstring
chainIdinteger
validUntilinteger

Unix ms. The build expires 10 minutes after creation; call refresh after this.

slippageBpsinteger

Only present on refresh responses: how many bps the output dropped versus the original build. 0 when the price didn't get worse.

Changes

No recorded changes to this operation across all 1 revision of this API.