{"openapi":"3.1.0","info":{"title":"Stableyard Intent Engine API","version":"1.0.0","description":"Cross-chain intent execution engine for the Stableyard V1 public API. This spec tracks the live runtime contract for quote, order, status, and config endpoints.\n\nBrowse this spec interactively at `/reference` (Scalar UI). Generate typed clients via `npx openapi-typescript /openapi.json -o api-types.ts`. The integrator walkthrough lives in `docs/INTEGRATING.md` in the repo (action-envelope shapes, error catalog, status lifecycle).","contact":{"name":"Stableyard","url":"https://stableyard.fi"}},"servers":[{"url":"https://routing-api.stableyard.fi","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Quote","description":"Price discovery across providers"},{"name":"Order","description":"Create, execute, and track bridge orders"},{"name":"Config","description":"Supported chains, tokens, routes"},{"name":"Portfolio","description":"Wallet balances across EVM, Solana, and Movement"},{"name":"Onramp","description":"Temporary fiat onramp integration"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Partner API key. Required for trusted orders and authenticated paths."}},"schemas":{"ChainInfo":{"type":"object","properties":{"chainId":{"type":"number","example":8453},"networkChainId":{"type":"number","description":"Legacy alias for chainId. New responses may omit this; use chainId as the source of truth.","example":8453},"name":{"type":"string","example":"base"},"displayName":{"type":"string","example":"Base"},"baseToken":{"type":"string","example":"ETH"},"logoURL":{"type":"string"},"explorerUrl":{"type":"string"}},"required":["chainId","name"]},"Amount":{"type":"object","properties":{"raw":{"type":"string","example":"10000000"},"formatted":{"type":"string","example":"10.000000"},"usd":{"type":"string","example":"10.00"}},"required":["raw","formatted"],"description":"Token amount with raw + display-formatted + optional USD representations."},"ActionToken":{"type":"object","properties":{"address":{"type":"string"},"symbol":{"type":"string"},"decimals":{"type":"integer","minimum":0},"logoURL":{"type":"string"}},"required":["address","symbol","decimals","logoURL"]},"ActionAmount":{"type":"object","properties":{"raw":{"type":"string"},"formatted":{"type":"string"},"usd":{"type":"string"}},"required":["raw","formatted","usd"]},"ActionRequirements":{"type":"object","properties":{"needsApproval":{"type":"boolean"},"transactionCount":{"type":"integer","minimum":0,"description":"User-signed transactions (0 for plain deposit_address transfers)."},"estimatedSeconds":{"type":"integer","minimum":0},"gaslessAvailable":{"type":"boolean"},"userActionRequired":{"type":"string","enum":["sign_tx","send_to_address","none"]},"requiresSeparateGasBalance":{"type":"boolean","description":"For deposit-address payments, fund network gas/withdrawal fees separately from the exact payment amount."},"paymentAmountMustNotBeReduced":{"type":"boolean","description":"Submit action.amount.raw or transactions[0].value exactly; never subtract gas or withdrawal fees from it."}},"required":["needsApproval","transactionCount","estimatedSeconds","gaslessAvailable","userActionRequired"]},"ActionTransaction":{"type":"object","properties":{"stepNumber":{"type":"integer","minimum":1,"description":"1-based ordering — first tx the user signs is stepNumber 1."},"to":{"type":"string"},"data":{"type":"string"},"value":{"type":"string"},"chainId":{"type":"number"},"gasLimit":{"type":"string"},"description":{"type":"string"}},"required":["stepNumber","to","data","value","chainId","description"]},"ActionApproval":{"type":["object","null"],"properties":{"needed":{"type":"boolean","enum":[true]},"tokenAddress":{"type":"string"},"spender":{"type":"string"},"amount":{"type":"string"},"transaction":{"$ref":"#/components/schemas/ActionTransaction"}},"required":["needed","tokenAddress","spender","amount","transaction"]},"ActionGasless":{"type":["object","null"],"properties":{"supported":{"type":"boolean","enum":[true]},"endpoint":{"type":"string"},"description":{"type":"string"}},"required":["supported","endpoint","description"]},"GatewayAction":{"type":"object","properties":{"kind":{"type":"string","enum":["gateway"]},"subtype":{"type":"string","description":"evm | movement","example":"evm"},"provider":{"type":"string"},"providerDisplayName":{"type":"string"},"chainId":{"type":"number"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"token":{"$ref":"#/components/schemas/ActionToken"},"amount":{"$ref":"#/components/schemas/ActionAmount"},"instructions":{"type":"array","items":{"type":"string"}},"requirements":{"$ref":"#/components/schemas/ActionRequirements"},"gatewayAddress":{"type":"string"},"transactions":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ActionTransaction"},"description":"EVM: [approve, deposit]. Null on quote responses."},"approval":{"$ref":"#/components/schemas/ActionApproval"},"movePayload":{"type":["object","null"],"properties":{"function":{"type":"string"},"typeArguments":{"type":"array","items":{"type":"string"}},"functionArguments":{"type":"array","items":{}}},"required":["function","typeArguments","functionArguments"],"description":"Movement only — Move VM entry function payload. Null on EVM."},"permitSupported":{"type":"boolean"},"gasless":{"$ref":"#/components/schemas/ActionGasless"}},"required":["kind","subtype","provider","providerDisplayName","chainId","chain","token","amount","instructions","requirements","gatewayAddress","transactions","approval","movePayload","permitSupported","gasless"]},"TransactionAction":{"type":"object","properties":{"kind":{"type":"string","enum":["transaction"]},"subtype":{"type":"string","enum":["cctp","xreserve","atomic_swap_bridge","movement_v2","composite_bridge","same_chain_swap"]},"provider":{"type":"string"},"providerDisplayName":{"type":"string"},"chainId":{"type":"number"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"token":{"$ref":"#/components/schemas/ActionToken"},"amount":{"$ref":"#/components/schemas/ActionAmount"},"instructions":{"type":"array","items":{"type":"string"}},"requirements":{"$ref":"#/components/schemas/ActionRequirements"},"transactions":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ActionTransaction"}},"approval":{"$ref":"#/components/schemas/ActionApproval"},"movePayload":{"type":["object","null"],"properties":{"function":{"type":"string"},"typeArguments":{"type":"array","items":{"type":"string"}},"functionArguments":{"type":"array","items":{}}},"required":["function","typeArguments","functionArguments"],"description":"Movement direct-transfer helper payload."},"solanaParams":{"type":["object","null"],"additionalProperties":{},"description":"Solana CCTP only. Pass-through for Circle SDK."}},"required":["kind","subtype","provider","providerDisplayName","chainId","chain","token","amount","instructions","requirements","transactions","approval","movePayload","solanaParams"]},"ActionPaymentRequest":{"type":["object","null"],"properties":{"qrUri":{"type":["string","null"],"description":"Chain-compatible URI for QR rendering, when available."},"standard":{"type":["string","null"],"enum":["eip681","solana_pay","bitcoin_uri","address_only"]},"displayAmount":{"type":"string"},"rawAmount":{"type":"string"},"amountIsExact":{"type":"boolean"},"copyAddress":{"type":["string","null"]},"copyAmount":{"type":"string"}},"required":["qrUri","standard","displayAmount","rawAmount","amountIsExact","copyAddress","copyAmount"],"description":"Use this for QR/manual deposit UX. It carries EIP-681, Solana Pay, or address-only metadata."},"DepositAddressAction":{"type":"object","properties":{"kind":{"type":"string","enum":["deposit_address"]},"subtype":{"type":"string","enum":["intent_boost","intent_movement_managed","intent_solana_managed","cctp_xreserve_boost","cctp_xreserve_managed","relay","near","tron_bridge"]},"provider":{"type":"string"},"providerDisplayName":{"type":"string"},"chainId":{"type":"number"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"token":{"$ref":"#/components/schemas/ActionToken"},"amount":{"$ref":"#/components/schemas/ActionAmount"},"instructions":{"type":"array","items":{"type":"string"}},"requirements":{"$ref":"#/components/schemas/ActionRequirements"},"address":{"type":["string","null"],"description":"Generated deposit address. Null on quote responses (allocated at order time)."},"transactions":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ActionTransaction"},"description":"Optional pre-built transfer calldata for boost flows."},"expiresAt":{"type":["number","null"],"description":"Unix ms when the address stops accepting deposits."},"providerRequestId":{"type":["string","null"],"description":"Provider-side external id (Relay/NEAR)."},"paymentRequest":{"$ref":"#/components/schemas/ActionPaymentRequest"},"gasless":{"$ref":"#/components/schemas/ActionGasless"}},"required":["kind","subtype","provider","providerDisplayName","chainId","chain","token","amount","instructions","requirements","address","transactions","expiresAt","providerRequestId","paymentRequest","gasless"]},"OrderAction":{"oneOf":[{"$ref":"#/components/schemas/GatewayAction"},{"$ref":"#/components/schemas/TransactionAction"},{"$ref":"#/components/schemas/DepositAddressAction"}],"discriminator":{"propertyName":"kind","mapping":{"gateway":"#/components/schemas/GatewayAction","transaction":"#/components/schemas/TransactionAction","deposit_address":"#/components/schemas/DepositAddressAction"}},"description":"The standardized envelope every /v1/quote and /v1/order response carries. Discriminated on `kind`. Quote responses leave concrete-execution fields (transactions, address, approval) null because they don't exist until the order is created — same shape, same `kind`, same `subtype`. The integrator's UI switches on `kind` and reads `requirements` to render the UX shell, then fills in transactions/address from the order response. Source of truth: src/lib/action-builder.ts."},"DestinationExtra":{"type":"object","properties":{"type":{"type":"string","enum":["gas_topup"]},"version":{"type":"string","example":"v1"},"chainId":{"type":"number","enum":[10002],"description":"Movement chain ID."},"token":{"type":"object","properties":{"address":{"type":"string","example":"0x0"},"symbol":{"type":"string","enum":["MOVE"]},"decimals":{"type":"number","enum":[8]},"logoURL":{"type":"string"}},"required":["address","symbol","decimals"]},"recipient":{"type":"string"},"amount":{"$ref":"#/components/schemas/Amount"},"policy":{"type":"string","enum":["top_up_if_below_target","exact"]},"targetBalanceRaw":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"maxAmountRaw":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"required":{"type":"boolean"},"executor":{"type":"string","enum":["backend"]},"sponsored":{"type":"boolean","enum":[true]},"status":{"type":"string","enum":["pending","not_required","completed","failed"]},"observedBalanceRaw":{"type":"string"},"txHash":{"type":"string"},"error":{"type":"string"},"attempts":{"type":"number"}},"required":["type","chainId","token","recipient","amount","policy","targetBalanceRaw","maxAmountRaw","required","executor","sponsored","status"],"description":"Backend-managed destination add-on. V1 supports a sponsored Movement MOVE gas top-up after USDCx delivery is verified."},"QuoteResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"message":{"type":"string"},"quoteId":{"type":"string","example":"0x7ccb4a16..."},"mode":{"type":"string","enum":["exact_input","exact_output"]},"routeType":{"type":"string"},"isComposite":{"type":"boolean"},"route":{"type":"object","properties":{"provider":{"type":"string","example":"intent"},"providerDisplayName":{"type":"string"},"isNative":{"type":"boolean"},"type":{"type":"string"}},"required":["provider","isNative"]},"tokenIn":{"type":"object","properties":{"chain":{"$ref":"#/components/schemas/ChainInfo"},"address":{"type":"string"},"symbol":{"type":"string"},"decimals":{"type":"number"},"amount":{"$ref":"#/components/schemas/Amount"}},"required":["chain","address","symbol","decimals","amount"]},"tokenOut":{"type":"object","properties":{"chain":{"$ref":"#/components/schemas/ChainInfo"},"address":{"type":"string"},"symbol":{"type":"string"},"decimals":{"type":"number"},"amount":{"type":"object","properties":{"expected":{"$ref":"#/components/schemas/Amount"},"minimum":{"$ref":"#/components/schemas/Amount"}},"required":["expected"]}},"required":["chain","address","symbol","decimals","amount"]},"exchangeRate":{"type":"string"},"priceImpact":{"type":"string"},"estimatedTime":{"type":"object","properties":{"seconds":{"type":"number"},"display":{"type":"string"}},"required":["seconds","display"]},"fees":{"type":"object","properties":{"total":{"$ref":"#/components/schemas/Amount"},"networkFee":{"allOf":[{"$ref":"#/components/schemas/Amount"},{"description":"On-chain gas cost estimate (USD-6)."}]},"platformFee":{"allOf":[{"$ref":"#/components/schemas/Amount"},{"description":"Platform fee (USD-6)."}]},"solverIncentive":{"allOf":[{"$ref":"#/components/schemas/Amount"},{"description":"Solver incentive portion (USD-6)."}]}},"required":["total"]},"slippage":{"type":"object","properties":{"perSwapBps":{"type":"number"},"totalBps":{"type":"number"},"percent":{"type":"string"}}},"steps":{"type":"array","items":{}},"intermediateToken":{},"alternatives":{"type":"array","items":{}},"expiresAt":{"type":"number","description":"Unix ms — 20s lock window."},"expiresIn":{"type":"number","description":"Seconds until expiry."},"action":{"$ref":"#/components/schemas/OrderAction"},"destinationExtras":{"type":"array","items":{"$ref":"#/components/schemas/DestinationExtra"},"description":"Additional destination-side work requested/managed by Stableyard. Currently only Movement MOVE gas top-up is supported."},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","quoteId","route","tokenIn","tokenOut","estimatedTime","fees","alternatives","expiresAt","action"]},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string","example":"Boost (deposit-address flow) is not available for this route."},"code":{"type":"string","description":"Machine-readable error code. Common values:\n\nQuote/routing:\n  INVALID_PARAMS, NO_QUOTES, PROVIDER_NOT_AVAILABLE, BOOST_NOT_AVAILABLE,\n  INSUFFICIENT_LIQUIDITY, MODE_MISMATCH_WITH_LOCKED_QUOTE\n\nLock/order:\n  NOT_FOUND, QUOTE_NOT_FOUND, QUOTE_ALREADY_USED, QUOTE_EXPIRED\n\nSubmit-tx verification (strictVerification=true orders):\n  TX_NOT_FOUND, TX_REVERTED, NO_MATCHING_EVENT, WRONG_QUOTE_ID,\n  WRONG_TOKEN, WRONG_AMOUNT, WRONG_RECIPIENT, WRONG_MINT_RECIPIENT,\n  WRONG_DOMAIN, MALFORMED_HOOK_DATA, MALFORMED_CALLDATA\n\nSubmit-tx 1-to-1 invariant:\n  DEPOSIT_TX_ALREADY_SET (409, order already has a different hash),\n  DEPOSIT_TX_DUPLICATE   (409, txHash already bound to another order)\n\nInfra:\n  RATE_LIMITED, INTERNAL_ERROR, VERIFICATION_FAILED, INTERNAL_API_UNAVAILABLE","example":"BOOST_NOT_AVAILABLE"},"requestId":{"type":"string","example":"7a9f..."},"availableProviders":{"type":"array","items":{}},"lockedProvider":{"type":"string"},"lockedDepositType":{"type":"string"},"requestedMode":{"type":"string"}},"required":["success","error","code"]},"DestinationGasTopUpRequest":{"anyOf":[{"type":"boolean"},{"type":"object","properties":{"enabled":{"type":"boolean"},"mode":{"type":"string","enum":["auto","exact"],"description":"`auto` tops up only if recipient MOVE balance is below target; `exact` always sends the requested MOVE amount."},"targetAmountRaw":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Target MOVE balance or exact amount, raw 8-decimal units.","example":"10000000"},"maxAmountRaw":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Safety cap for auto top-up, raw 8-decimal units.","example":"10000000"},"required":{"type":"boolean","description":"When true, order completion waits for the top-up to succeed."}}}],"description":"Movement destination only. true requests an auto MOVE gas top-up; false disables it for this quote when globally enabled."},"QuoteRequest":{"type":"object","properties":{"sourceChainId":{"type":"integer","exclusiveMinimum":0,"description":"Source chain ID","example":8453},"destChainId":{"type":"integer","exclusiveMinimum":0,"example":42161},"sourceToken":{"type":"string","minLength":1,"example":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},"destToken":{"type":"string","minLength":1,"example":"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},"sourceAmount":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"destAmount":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"mode":{"type":"string","enum":["exact_input","exact_output"],"default":"exact_input"},"recipient":{"type":"string","minLength":1,"description":"Chain-native address. EVM: 0x-prefixed hex. Solana: base58. Movement: 32-byte hex. Tron: base58 (T-prefix). Bitcoin: base58/bech32.","example":"0x55Ab3B66D644e17FDb0C476bB76B4e9b8818f9FB"},"slippageBps":{"type":"integer","minimum":0,"maximum":1000,"default":50,"example":50},"partnerFeeBps":{"type":"integer","minimum":0,"maximum":1000,"description":"Authenticated partner fee override in bps. Currently honored only for same-chain same-token deposit-address routes when the partner has request overrides enabled in admin.","example":50},"providers":{"type":"array","items":{"type":"string"},"minItems":1,"example":["relay","intent"]},"private":{"type":"boolean","description":"Request private handling where available. Same-chain EVM private quotes use deposit-address UX."},"privacyFallback":{"type":"boolean","description":"With private=true, allow fallback from solver-pool privacy to CREATE2 deposit-forwarder when liquidity is unavailable. Defaults to true."},"destinationGasTopUp":{"$ref":"#/components/schemas/DestinationGasTopUpRequest"},"executionMode":{"type":"string","enum":["standard","atomic","deposit_address","boosted"],"description":"Flow shape. `deposit_address` asks for a single-transfer deposit-address UX on any provider (falls back native CREATE2 boost → Relay → NEAR; 400s with BOOST_NOT_AVAILABLE if none can serve). `boosted` is a deprecated alias for `deposit_address`, accepted for backward compatibility."},"sourceAddress":{"type":"string","minLength":1,"description":"Optional source-chain sender/refund address. Tron: base58 T-prefix. Bitcoin: base58/bech32. Providers fall back to chain-specific placeholders for dry quotes when omitted."},"callData":{"type":"string","description":"Destination action intent calldata. Supported only on routes executed by the native intent provider."}},"required":["sourceChainId","destChainId","sourceToken","destToken","recipient"]},"OrderResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"quoteId":{"type":"string","description":"Same value as orderId — both are the 32-byte request identifier. quoteId is always populated; orderId appears once an Order record exists (post-deposit for native/boost; synchronously for provider flows)."},"orderId":{"type":"string","description":"Same value as quoteId. Present when an Order record has been materialized."},"status":{"type":"string","enum":["awaiting_deposit","ready_to_execute","awaiting_source_swap"],"description":"Lifecycle state at order-creation response. The `action` envelope is always present; this field hints at what the integrator must do next:\n  awaiting_deposit → action.kind=deposit_address (send tokens to action.address)\n  ready_to_execute → action.kind=gateway|transaction (sign action.transactions[])\n  awaiting_source_swap → composite swap path; sign action.transactions[0] (the swap), then send swap output to action.address"},"statusMessage":{"type":"string"},"routeType":{"type":"string","enum":["direct","swap_only","source_swap_bridge","bridge_dest_swap","full_composite","privacy_transfer","bridge_dest_bridge"]},"isComposite":{"type":"boolean"},"action":{"$ref":"#/components/schemas/OrderAction"},"destinationExtras":{"type":"array","items":{"$ref":"#/components/schemas/DestinationExtra"},"description":"Additional destination-side work requested/managed by Stableyard. Currently only Movement MOVE gas top-up is supported."},"intermediateToken":{"type":"object","properties":{"symbol":{"type":"string"},"address":{"type":"string"},"bridgeAmount":{"type":"string"}},"required":["symbol","address","bridgeAmount"]},"route":{"type":"object","properties":{"provider":{"type":"string"},"providerDisplayName":{"type":"string"},"isNative":{"type":"boolean"},"type":{"type":"string"}},"required":["provider"]},"recipient":{"type":"object","properties":{"address":{"type":"string"},"chain":{"$ref":"#/components/schemas/ChainInfo"}},"required":["address","chain"]},"quote":{"type":"object","properties":{"expiresAt":{"type":"number"},"expiresIn":{"type":"number"},"tokenIn":{},"tokenOut":{},"exchangeRate":{"type":"string"},"estimatedTime":{"type":"object","properties":{"seconds":{"type":"number"},"display":{"type":"string"}},"required":["seconds","display"]}},"required":["expiresAt","expiresIn","estimatedTime"]},"alternatives":{"type":"array","items":{}},"timestamps":{"type":"object","properties":{"created":{"type":"string"},"expiresAt":{"type":"string"}},"required":["created","expiresAt"]},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","quoteId","status","action"]},"OrderRequest":{"type":"object","properties":{"sourceChainId":{"type":"integer","exclusiveMinimum":0,"example":8453},"destChainId":{"type":"integer","exclusiveMinimum":0,"example":42161},"sourceToken":{"type":"string","minLength":1},"destToken":{"type":"string","minLength":1},"sourceAmount":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"destAmount":{"type":"string","pattern":"^(0|[1-9][0-9]*)$","description":"Raw token amount (non-negative integer string, already scaled by decimals).","example":"10000000"},"mode":{"type":"string","enum":["exact_input","exact_output"],"default":"exact_input"},"recipient":{"type":"string","minLength":1,"description":"Chain-native address. EVM: 0x-prefixed hex. Solana: base58. Movement: 32-byte hex. Tron: base58 (T-prefix). Bitcoin: base58/bech32.","example":"0x55Ab3B66D644e17FDb0C476bB76B4e9b8818f9FB"},"slippageBps":{"type":"integer","minimum":0,"maximum":1000,"default":50},"partnerFeeBps":{"type":"integer","minimum":0,"maximum":1000,"description":"Authenticated partner fee override in bps. Must match the locked quote when quoteId is used."},"preferredProvider":{"type":"string","description":"Hard-require a specific provider — 400 if unavailable."},"executionMode":{"type":"string","enum":["standard","atomic","deposit_address","boosted"],"description":"Flow shape. `deposit_address` asks for a single-transfer deposit-address UX on any provider (falls back native CREATE2 boost → Relay → NEAR; 400s with BOOST_NOT_AVAILABLE if none can serve). `boosted` is a deprecated alias for `deposit_address`, accepted for backward compatibility."},"providers":{"type":"array","items":{"type":"string"},"minItems":1},"callData":{"type":"string","description":"Action intent calldata (ExecutionEnvironment format)."},"private":{"type":"boolean","description":"Hide from /v1/orders; mask details for non-owners."},"privacyFallback":{"type":"boolean","description":"With private=true, allow fallback from solver-pool privacy to CREATE2 deposit-forwarder when liquidity is unavailable. Defaults to true."},"destinationGasTopUp":{"allOf":[{"$ref":"#/components/schemas/DestinationGasTopUpRequest"},{"description":"Movement destination only. true requests an auto MOVE gas top-up; false disables it for this order when globally enabled."}]},"sourceAddress":{"type":"string","minLength":1},"quoteId":{"type":"string","minLength":1,"description":"Lock this order to a previously-issued quote. Pins price + provider. See QUOTE_ALREADY_USED / QUOTE_EXPIRED."}},"required":["sourceChainId","destChainId","sourceToken","destToken","recipient"]},"StatusAmount":{"type":"object","properties":{"raw":{"type":"string"},"formatted":{"type":"string"},"usd":{"type":["string","null"]},"inferred":{"type":"boolean","description":"true when the value was defaulted because the solver did not report an authoritative amount (e.g. native boost orders)."},"verified":{"type":"boolean","description":"true when the amount was observed on-chain (authoritative). false when the value is provider-reported or inferred."},"source":{"type":"string","enum":["on-chain","provider","quoted"],"description":"Where the number came from. \"on-chain\" = read from deposit address balance or bridge receipt event. \"provider\" = reported by Relay/NEAR/relayer. \"quoted\" = fell back to the quoted value (no observation)."}},"required":["raw","formatted"]},"OrderStatusResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"orderId":{"type":"string","description":"Same value as quoteId — both are the 32-byte request identifier. Either can be used to look up the order."},"quoteId":{"type":"string","description":"Same value as orderId. Included for callers that kept the quoteId from POST /v1/quote."},"status":{"type":"object","properties":{"code":{"type":"string","enum":["pending","accepted","in_progress","completed","failed","refunded"]},"display":{"type":"string"},"isTerminal":{"type":"boolean"},"progress":{"type":"number"},"description":{"type":"string"}},"required":["code","display","isTerminal","progress"]},"softConfirmation":{"type":"object","properties":{"enabled":{"type":"boolean"},"accepted":{"type":"boolean"},"reason":{"type":["string","null"],"enum":["source_funds_verified"]},"terminal":{"type":"boolean"}},"required":["enabled","accepted","reason","terminal"],"description":"Present on order responses. When `softConfirmation=true`, accepted=true means the source payment was verified and Stableyard has accepted settlement responsibility, but the order is still non-terminal."},"destinationExtras":{"type":"array","items":{"$ref":"#/components/schemas/DestinationExtra"},"description":"Additional destination-side work requested/managed by Stableyard. Currently only Movement MOVE gas top-up is supported."},"tokenIn":{"type":"object","properties":{"address":{"type":"string"},"symbol":{"type":"string"},"decimals":{"type":"number"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"amount":{"type":"object","properties":{"raw":{"type":"string"},"formatted":{"type":"string"},"usd":{"type":["string","null"]},"quoted":{"$ref":"#/components/schemas/StatusAmount"}},"required":["raw","formatted"]}},"required":["address","symbol","decimals","amount"]},"tokenOut":{"type":"object","properties":{"address":{"type":"string"},"symbol":{"type":"string"},"decimals":{"type":"number"},"chain":{"$ref":"#/components/schemas/ChainInfo"},"amount":{"type":"object","properties":{"expected":{"$ref":"#/components/schemas/StatusAmount"},"quoted":{"$ref":"#/components/schemas/StatusAmount"},"minimum":{"allOf":[{"$ref":"#/components/schemas/StatusAmount"},{"type":["object","null"]}]},"actual":{"allOf":[{"$ref":"#/components/schemas/StatusAmount"},{"type":["object","null"],"description":"Solver-reported fill. For completed native/boost orders where the solver did not report a fill, the engine falls back to `quoted` with `inferred: true`. Always non-null for completed orders."}]}}}},"required":["address","symbol","decimals","amount"]},"fees":{"type":"object","properties":{"reliable":{"type":"boolean","description":"true when the chain priceProvider could price both tokens. false for unknown/unlisted tokens — USD math is suppressed to avoid emitting misleading values. Fall back to raw token amounts from tokenIn/tokenOut."},"quoted":{"type":["object","null"],"properties":{"usd":{"type":"string"}},"required":["usd"]},"actual":{"type":["object","null"],"properties":{"usd":{"type":"string"},"deltaUsd":{"type":"string","description":"quoted.usd − actual.usd. Positive = user came out ahead."},"inferred":{"type":"boolean"}},"required":["usd","deltaUsd","inferred"]},"partnerFee":{"type":["object","null"],"properties":{"raw":{"type":"string"},"formatted":{"type":"string"},"usd":{"type":"string"},"bps":{"type":"number"},"recipient":{"type":["string","null"]},"txHash":{"type":["string","null"]}},"required":["raw","formatted","usd","bps","recipient","txHash"],"description":"Explicit partner-fee split for backend-quoted same-chain direct deposit flows."}},"required":["reliable","quoted","actual"]},"addresses":{"type":"object","properties":{"deposit":{"type":["string","null"]},"depositor":{"type":["string","null"],"description":"Original sender on source chain (used for refunds)."},"recipient":{"type":"string"},"solver":{"type":["string","null"]}}},"transactions":{"type":"object","properties":{"deposit":{},"execution":{},"destination":{},"refund":{},"sweep":{"description":"Source-chain sweep tx when the sweeper drained the deposit. Null for non-CREATE2 flows or when a sentinel was stored."}}},"route":{},"timing":{"type":"object","properties":{"estimatedSeconds":{"type":"number"},"settlementSeconds":{"type":["number","null"],"description":"deposited→completed. \"How fast did we settle.\""},"totalSeconds":{"type":["number","null"],"description":"created→completed. Includes user deposit time."},"actualSeconds":{"type":["number","null"],"description":"Alias of settlementSeconds (backward-compat)."},"measurementSource":{"type":"string","enum":["on_chain","backend_observed"],"description":"Whether settlementSeconds uses destination block time or backend observation time."},"observationLagSeconds":{"type":["number","null"],"description":"Delay between destination-chain settlement and backend completion observation."},"display":{"type":"string"},"fasterThanEstimate":{"type":["boolean","null"]}},"required":["estimatedSeconds","settlementSeconds","totalSeconds","actualSeconds","measurementSource","observationLagSeconds","display","fasterThanEstimate"]},"timestamps":{},"routeType":{"type":"string"},"depositDetails":{},"partner":{"type":["object","null"],"properties":{"id":{"type":"string"}},"required":["id"],"description":"Set when the order was created with a partner API key."},"trustedOrder":{"type":["object","null"],"properties":{"creditRecorded":{"type":"boolean"},"creditAmount":{"type":["string","null"]},"creditTxHash":{"type":["string","null"]},"creditRecordedAt":{"type":["string","null"]},"repaid":{"type":"boolean"},"repaymentTxHash":{"type":["string","null"]},"repaymentDeadline":{"type":["string","null"]}},"required":["creditRecorded","creditAmount","creditTxHash","creditRecordedAt","repaid","repaymentTxHash","repaymentDeadline"]},"masked":{"type":"boolean","description":"true when a private order is accessed without the owning partner API key — amounts, recipient, tokens hidden."},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","orderId","status"]},"OrdersListResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"orders":{"type":"array","items":{}},"pagination":{"type":"object","properties":{"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"},"hasMore":{"type":"boolean"},"currentPage":{"type":"number"},"totalPages":{"type":"number"}},"required":["total","limit","offset","hasMore","currentPage","totalPages"]},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","orders"]},"SubmitTxRequest":{"type":"object","properties":{"txHash":{"type":"string","minLength":1,"description":"Source-chain deposit tx hash","example":"0x07bff59daf46d05c..."}},"required":["txHash"]},"NetworkCapabilities":{"type":"object","properties":{"wallet":{"type":"object","additionalProperties":{"type":"boolean"}},"depositAddress":{"type":"object","additionalProperties":{"type":"boolean"}},"privacy":{"type":"object","additionalProperties":{"type":"boolean"}},"supportedModes":{"type":"object","properties":{"wallet":{"type":"object","properties":{"sameChainSameToken":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"sameChainStableSwap":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"crossChainSource":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}}},"required":["sameChainSameToken","sameChainStableSwap","crossChainSource"]},"deposit_address":{"type":"object","properties":{"sameChainSameToken":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"sameChainStableSwap":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"crossChainSource":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}}},"required":["sameChainSameToken","sameChainStableSwap","crossChainSource"]}},"required":["wallet","deposit_address"]},"notes":{"type":"array","items":{"type":"string"}}},"required":["wallet","depositAddress","privacy","supportedModes","notes"]},"ConfigChain":{"allOf":[{"$ref":"#/components/schemas/ChainInfo"},{"type":"object","properties":{"chainType":{"type":"string","enum":["evm","solana","move","tron","bitcoin"]},"isEvm":{"type":"boolean"},"tokenCount":{"type":"number"},"capabilities":{"$ref":"#/components/schemas/NetworkCapabilities"}}}]},"RouteMatrixEntry":{"type":"object","properties":{"from":{"type":"object","properties":{"chainId":{"type":"number"},"networkChainId":{"type":"number"},"name":{"type":"string"}},"required":["chainId","networkChainId","name"]},"to":{"type":"object","properties":{"chainId":{"type":"number"},"networkChainId":{"type":"number"},"name":{"type":"string"}},"required":["chainId","networkChainId","name"]},"providers":{"type":"array","items":{"type":"string"}},"estimatedTime":{"type":"string"},"supportedActionTypes":{"type":"array","items":{"type":"string","enum":["transaction","deposit_address","gateway"]}},"defaultActionType":{"type":"string","enum":["transaction","deposit_address","gateway"]},"executionModes":{"type":"array","items":{"type":"string","enum":["standard","deposit_address","atomic"]}},"depositAddressAvailability":{"type":"string","enum":["never","conditional","default"]},"supportedModes":{"type":"object","properties":{"wallet":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"deposit_address":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}}},"required":["wallet","deposit_address"]},"supportedModesByRouteType":{"type":"object","properties":{"sameChainSameToken":{"type":"object","properties":{"wallet":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"deposit_address":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}}},"required":["wallet","deposit_address"]},"sameChainStableSwap":{"type":"object","properties":{"wallet":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}},"deposit_address":{"type":"array","items":{"type":"string","enum":["exact_input","exact_output"]}}},"required":["wallet","deposit_address"]}},"required":["sameChainSameToken","sameChainStableSwap"]},"supportLevel":{"type":"string","enum":["general","token_restricted","provider_limited"]},"constraints":{"type":"array","items":{"type":"string"}}},"required":["from","to","providers","estimatedTime","supportedActionTypes","defaultActionType","executionModes","depositAddressAvailability","supportedModes"]},"TokenInfo":{"type":"object","properties":{"address":{"type":"string","example":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},"symbol":{"type":"string","example":"USDC"},"decimals":{"type":"number","example":6},"logoURL":{"type":"string"}},"required":["address","symbol","decimals"]},"ConfigToken":{"allOf":[{"$ref":"#/components/schemas/TokenInfo"},{"type":"object","properties":{"name":{"type":"string"}}}]},"ConfigResponse":{"anyOf":[{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"networks":{"type":"array","items":{"$ref":"#/components/schemas/ConfigChain"}},"tokens":{"type":"array","items":{}},"routes":{"type":"array","items":{"$ref":"#/components/schemas/RouteMatrixEntry"}},"fees":{},"api":{},"limits":{},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","networks","tokens","routes","meta"]},{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"chain":{"$ref":"#/components/schemas/ConfigChain"},"tokens":{"type":"array","items":{"$ref":"#/components/schemas/ConfigToken"}},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","chain","tokens","meta"]}]},"ChainsResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"count":{"type":"number"},"chains":{"type":"array","items":{"$ref":"#/components/schemas/ConfigChain"}},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","count","chains"]},"TokensResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"chainId":{"type":"number"},"chain":{"type":"string"},"count":{"type":"number"},"tokens":{"type":"array","items":{"$ref":"#/components/schemas/ConfigToken"}},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","count","tokens"]},"RoutesResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"totalRoutes":{"type":"number"},"routes":{"type":"array","items":{"$ref":"#/components/schemas/RouteMatrixEntry"}},"meta":{"type":"object","properties":{"version":{"type":"string"},"requestId":{"type":"string"}},"required":["version","requestId"]}},"required":["success","totalRoutes","routes"]},"PortfolioToken":{"type":"object","properties":{"address":{"type":"string","description":"Token contract address (EVM ERC20), SPL mint (Solana), or Move resource (Movement). Zero address for EVM native.","example":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},"symbol":{"type":"string","example":"USDC"},"name":{"type":"string","example":"USD Coin"},"decimals":{"type":"number","example":6},"logoURL":{"type":"string","example":"https://…/usdc.png"},"isNative":{"type":"boolean","description":"true for chain gas token (ETH/POL/SOL/MOVE/...)"},"isStablecoin":{"type":"boolean","description":"true for USD-pegged assets such as USDC, USDT, PYUSD, USDCx, and PathUSD"}},"required":["address","symbol","name","decimals","logoURL","isNative","isStablecoin"]},"PortfolioBalance":{"type":"object","properties":{"chainId":{"type":"number","example":8453},"chainName":{"type":"string","example":"base"},"family":{"type":"string","enum":["evm","solana","movement"]},"token":{"$ref":"#/components/schemas/PortfolioToken"},"rawBalance":{"type":"string","description":"On-chain amount in atomic units (BigInt as string).","example":"14886380"},"formattedBalance":{"type":"string","example":"14.88638"},"usdValue":{"type":["string","null"],"description":"USD-6 string for stablecoins (1:1 peg). null for native tokens — no spot price embedded.","example":"14886380"},"eligible":{"type":"boolean","description":"true if no `minUsd` was passed, or if this is a stablecoin whose USD value ≥ minUsd. Always false for native tokens when minUsd is set (no price feed)."}},"required":["chainId","chainName","family","token","rawBalance","formattedBalance","usdValue","eligible"]},"PortfolioChainError":{"type":"object","properties":{"chainId":{"type":"number"},"reason":{"type":"string"}},"required":["chainId","reason"]},"PortfolioResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"address":{"type":"string","example":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"},"family":{"type":"string","enum":["evm","solana","movement"]},"chains":{"type":"array","items":{"type":"number"},"description":"Chain IDs that were queried.","example":[1,8453,42161,137]},"minUsdRaw6":{"type":["string","null"],"example":"10000000"},"totalUsdRaw6":{"type":"string","example":"784392530"},"totalUsd":{"type":"string","example":"784.39"},"balances":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioBalance"}},"eligibleCount":{"type":"number","example":5},"errors":{"type":"array","items":{"$ref":"#/components/schemas/PortfolioChainError"}},"meta":{"type":"object","properties":{"version":{"type":"string"},"timestamp":{"type":"number"},"requestId":{"type":"string"}},"required":["version","timestamp","requestId"]}},"required":["success","address","family","chains","minUsdRaw6","totalUsdRaw6","totalUsd","balances","eligibleCount","errors"]},"OnrampConfigResponse":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"providers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["banxa"]},"enabled":{"type":"boolean"},"configured":{"type":"boolean"}},"required":["provider","enabled","configured"]}},"enabledProviders":{"type":"array","items":{"type":"string","enum":["banxa"]}},"defaultProvider":{"type":"string","enum":["banxa"]}},"required":["success","providers","enabledProviders","defaultProvider"]},"OnrampSessionResponse":{"type":"object","properties":{"provider":{"type":"string","enum":["banxa"]},"orderId":{"type":"string"},"checkoutUrl":{"type":"string","format":"uri"},"status":{"type":"string"},"order":{},"session":{}},"required":["provider","orderId","checkoutUrl"]},"OnrampSessionRequest":{"type":"object","properties":{"provider":{"type":"string","enum":["auto","banxa"],"default":"banxa"},"receiptEmail":{"type":"string","format":"email","example":"buyer@example.com"},"amount":{"type":"number","exclusiveMinimum":0,"maximum":1000000,"description":"Fiat amount.","example":100},"walletAddress":{"type":"string","minLength":3,"maxLength":256,"example":"0xdFD4ab80E163D6864E26F37540563cBf2E52A582"},"network":{"type":"string","description":"Delivery network alias understood by Banxa.","example":"base"},"chain":{"type":"string","description":"Alias for network."},"cryptoCurrencyCode":{"type":"string","example":"USDC"},"fiatCurrency":{"type":"string","minLength":3,"maxLength":3,"example":"USD"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"Alias for fiatCurrency."},"redirectUrl":{"type":"string","format":"uri"},"reference":{"type":"string","maxLength":128},"paymentMethodId":{"type":"string","maxLength":128},"externalCustomerId":{"type":"string","maxLength":256},"mode":{"type":"string","maxLength":64},"metadata":{"type":"object","additionalProperties":{}}},"required":["receiptEmail","amount","walletAddress"]}},"parameters":{}},"paths":{"/v1/quote":{"post":{"tags":["Quote"],"summary":"Get a bridge quote","description":"Returns the best available route across all providers for the requested token pair, with alternatives. Pass the returned `quoteId` to `POST /v1/order` within the 20-second lock window to pin the price.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteRequest"}}}},"responses":{"200":{"description":"Quote found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteResponse"}}}},"404":{"description":"No route available","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/order":{"post":{"tags":["Order"],"summary":"Create an order","description":"Creates a bridge order. Response carries a single `action` envelope — a discriminated union on `action.kind` (`gateway` | `transaction` | `deposit_address`). Same shape is previewed on /v1/quote with concrete-execution fields (transactions, address, approval) nulled. See the \"action envelope contract\" section in docs/INTEGRATING.md for the full type. Pass `quoteId` from a prior `/v1/quote` to lock price. Pass `executionMode: \"deposit_address\"` (alias: `\"boosted\"`) to hard-require a single-transfer deposit-address flow (rejected with BOOST_NOT_AVAILABLE if unavailable).","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderRequest"}}}},"responses":{"200":{"description":"Order created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderResponse"}}}},"400":{"description":"Invalid params / mode mismatch / boost unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Quote or route not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Quote already used","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"Quote expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/order/{id}":{"get":{"tags":["Order"],"summary":"Get order status","description":"Fetch order state by `orderId` (or `quoteId` — they are the same once the order is materialized). Private orders return masked details (status + chain IDs + timestamps only) unless the owning partner API key is provided.","parameters":[{"schema":{"type":"string","description":"orderId or quoteId (they hold the same value)","example":"0x..."},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["true","false"],"description":"Opt-in public status projection. When true, source-verified in-progress orders with no destination fill yet return status.code=accepted.","example":"true"},"required":false,"name":"softConfirmation","in":"query"}],"responses":{"200":{"description":"Order state (or masked for private orders)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderStatusResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/orders":{"get":{"tags":["Order"],"summary":"List recent orders","description":"Lists non-private orders. Filter by `partnerId`, `status`, pagination with `limit`/`page`. Private orders are excluded unless the owning partner API key is provided.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","minimum":1,"example":1},"required":false,"name":"page","in":"query"},{"schema":{"type":"string","enum":["pending","in_progress","completed","failed","refunded"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","enum":["true","false"],"description":"Opt-in public status projection for rows. When true, eligible in-progress rows return status=accepted.","example":"true"},"required":false,"name":"softConfirmation","in":"query"},{"schema":{"type":"string"},"required":false,"name":"partnerId","in":"query"}],"responses":{"200":{"description":"List of orders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrdersListResponse"}}}}}}},"/v1/order/{id}/submit-tx":{"post":{"tags":["Order"],"summary":"Submit deposit transaction hash","description":"After the user signs and submits their deposit on-chain, the frontend reports the tx hash here so the engine can immediately attach it to the order and trigger execution. Falls back to backend polling (depositMonitor) if never called — but primary path for fast UX. For native (gateway) flows the engine parses the gateway Deposit event from the receipt; for deposit-address flows it verifies the CREATE2 balance.","parameters":[{"schema":{"type":"string","description":"orderId or quoteId","example":"0x..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitTxRequest"}}}},"responses":{"200":{"description":"Deposit verified, order progressed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"message":{"type":"string","example":"Deposit verified and order created"},"orderId":{"type":"string"},"quoteId":{"type":"string"},"status":{"type":"string"}},"required":["success","message","orderId","quoteId","status"]}}}},"400":{"description":"Amount too low / no deposit / no event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Order/quote not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"VERIFICATION_FAILED — on-chain check threw","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/config":{"get":{"tags":["Config"],"summary":"Get the complete routing configuration","description":"Returns networks, tokens, route capabilities, and structured quote-mode support. Use each route supportedModes field, and supportedModesByRouteType for same-chain flows, before requesting a quote.","parameters":[{"schema":{"type":["integer","null"],"example":8453},"required":false,"name":"chainId","in":"query"}],"responses":{"200":{"description":"Routing configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigResponse"}}}}}}},"/v1/chains":{"get":{"tags":["Config"],"summary":"List supported chains","responses":{"200":{"description":"Chain registry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChainsResponse"}}}}}}},"/v1/tokens":{"get":{"tags":["Config"],"summary":"List supported tokens","description":"Filter with `?chainId=...` to scope to one chain.","parameters":[{"schema":{"type":["integer","null"],"example":8453},"required":false,"name":"chainId","in":"query"}],"responses":{"200":{"description":"Token registry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokensResponse"}}}}}}},"/v1/routes":{"get":{"tags":["Config"],"summary":"List supported routes","description":"Every source→dest token pair the engine can serve. Filter with `?sourceChainId=...` to scope.","parameters":[{"schema":{"type":["integer","null"],"example":8453},"required":false,"name":"sourceChainId","in":"query"}],"responses":{"200":{"description":"Route registry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutesResponse"}}}}}}},"/v1/portfolio":{"get":{"tags":["Portfolio"],"summary":"Wallet portfolio across EVM, Solana, and Movement","description":"Returns stablecoin + native balances for a wallet, with USD valuation and eligibility flagging. The `address` family is auto-detected by format:\n- `0x{40 hex}` → **EVM** (fans out across configured chains via a single Multicall3 per chain)\n- `0x{41-64 hex}` → **Movement** (Aptos `/view` for USDCx + APT)\n- `base58 {32-44}` → **Solana** (JSON-RPC batch: `getBalance` + `getTokenAccountsByOwner` per supported mint)\n\n`chainIds` only narrows the EVM fan-out. `minUsd` (decimal USD) flips the per-balance `eligible` flag — useful when rendering a 'pay $X' picker (eligible-first sort, then USD desc). Native balances return `usdValue: null` (no embedded price feed — frontend should price separately if a $-threshold matters for natives).","parameters":[{"schema":{"type":"string","description":"Wallet address. Family auto-detected.","example":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"},"required":true,"name":"address","in":"query"},{"schema":{"type":"string","description":"Comma-separated EVM chain IDs to query (ignored for Solana/Movement).","example":"1,8453,42161,137"},"required":false,"name":"chainIds","in":"query"},{"schema":{"type":["number","null"],"minimum":0,"description":"Eligibility threshold in USD decimal (e.g. 10 = $10).","example":10},"required":false,"name":"minUsd","in":"query"}],"responses":{"200":{"description":"Portfolio","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortfolioResponse"}}}},"400":{"description":"Invalid address or query","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/onramp/config":{"get":{"tags":["Onramp"],"summary":"Get fiat onramp availability","description":"Temporary Banxa capability endpoint used by the Stableyard widget.","security":[],"responses":{"200":{"description":"Onramp provider configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnrampConfigResponse"}}}}}}},"/v1/onramp/session":{"post":{"tags":["Onramp"],"summary":"Create a Banxa checkout session","description":"Creates a server-authenticated Banxa buy order and returns its hosted checkout URL. Public and rate-limited by client IP; Banxa credentials remain server-side.","security":[],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnrampSessionRequest"}}}},"responses":{"200":{"description":"Banxa checkout created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnrampSessionResponse"}}}},"400":{"description":"Invalid request or provider rejection","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"Banxa unavailable or invalid response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Banxa disabled or not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}