Skip to main content
POST
Returns one executable, signed quote for moving a stablecoin between chains, or within a chain, for source.funder. type fixes either source.amount (exact-in) or destination.amount (exact-out); custom requires user-authored destination.calls. dappId is required. The response is a top-level quote object with the transaction to send from the funder (execution.transaction), the decoded intent, destination.amountOut and minAmountOut, fees, per-step intents, and expiresAt. signature verifies against the source chain’s quoteSigner from GET /v1/chains; the returned intentHash is the handle for GET /v1/intents/status. An unsupported chain returns 422 chain-not-supported. Routes no solver will fill (unlisted tokens, unavailable liquidity, amounts above what solvers hold) currently return 502 solver-error. Requires x-api-key. Partner pricing, attribution, and enabled features are tied to the key. Without a key the gateway answers 403 with a plain JSON body ({"Message": "User is not authorized ..."}); a key that is unknown, revoked, or not enabled for v1 answers 401 invalid-api-key. No requests-per-second quota is published. Handle 429 and honor Retry-After when present. Examples use real mainnet token and contract addresses with placeholder wallets, hashes, signatures, and IDs.

Authorizations

x-api-key
string
header
required

Body

application/json
type
enum<string>
required

Which amount is fixed. exact-in: source.amount is spent and destination.minAmountOut is guaranteed. exact-out: destination.amount arrives and the response's source.amount is the required input. custom: source.amount is spent and the supplied destination.calls execute on the destination chain.

Available options:
exact-in,
exact-out,
custom
source
object
required
destination
object
required
dappId
string
required

Required. Attribution label for the integration. Does not authenticate and does not change pricing.

Required string length: 1 - 128
refundRecipient
string

Receives the source funds if the intent is refunded. Defaults to source.funder. Address on the source chain.

slippage
number

Decimal fraction of the destination amount: 0.005 = 0.5%. Range 0.0001-1; a percent-style 0.5 would mean 50%.

Required range: 0.0001 <= x <= 1
options
object

Response

The winning quote. Verify signature against the source chain's quoteSigner, then fund before expiresAt.

id
string
required

Quote ID, prefixed quote:. Status lookups take the bare UUID.

type
enum<string>
required

Echo of the request type.

Available options:
exact-in,
exact-out,
custom
source
object
required
destination
object
required
slippage
number
required

Tolerance actually bound into destination.minAmountOut, as a decimal fraction

fees
object[]
required

Fees charged for the whole quote, by type (gas, proving, protocol, gateway). estimate: false means the amount is binding.

steps
object[]
required

Ordered legs of the route. Each step names its provider and lists the intents it is realized by, with the full decoded intent. A stitched-destination intent credits the recipient on a multi-hop route and is the one to track for delivery; bucket-candidate entries are alternative routes, not all of which fill.

solver
object
required

The solver that will fulfil the intent.

intentHash
string | null
required

Hash of the primary intent; the handle for GET /v1/intents/status?intentHash=. Null when every intent is listed under steps[].intents.

execution
object | null
required

Everything needed to fund the quote: the ready-to-send transaction, the decoded intent (route and reward), and the vault the source Portal funds the intent through, which is also the counterparty for gasless submits. Sent as-is.

expiresAt
integer
required

Quote expiry, Unix seconds. Covered by signature. Fund before it passes; afterwards request a new quote.

signature
string
required

EIP-712 signature by the source chain's quoteSigner (see GET /v1/chains) over Quote(string id, bytes32[] intentHashes, uint64 expiresAt) with domain { name: "EcoQuoteV1", version: "1", chainId: source.chainId }. intentHashes is intentHash plus every steps[].intents[].intentHash, lowercased, de-duplicated, sorted ascending.

quotes
object[] | null
required

Every competing quote, ranked best first, when options.allQuotes is true; each entry is independently signed. Null otherwise. The top-level object is always the winner.