For authentication, error codes, and request conventions, see API Overview.
GET /v1/orchestration/routes
List all supported trading pairs. No authentication required. Response:(sourceChain, sourceAsset) -> (destinationChain, destinationAsset) pair that can be used with /estimate, /quote, and /submit. The list is derived from the pipeline route resolver and stays in sync automatically as new pairs are added.
GET /v1/orchestration/estimate
Lightweight price preview. This does not create a quote and does not write to the database. Query parameters:| Param | Required | Notes |
|---|---|---|
sourceChain | Yes | One of the supported chains |
sourceAsset | Yes | One of the supported assets |
destinationChain | Yes | One of the supported chains |
destinationAsset | Yes | One of the supported assets |
amount | Yes | Integer string |
feeAsset is USDC for most routes and USDB for BTC -> USDB.
POST /v1/orchestration/quote
Request a durable quote with deposit instructions. Quotes expire 30 minutes after creation. Exact-in example (default mode):bitcoin:BTC -> base|solana:USDC):
-> lightning:BTC):
spark:BTC -> solana:USDC):
spark:BTC -> solana:USDC):
solana:SOL -> spark:BTC):
amountModedefaults toexact_in.amountMode=exact_outis supported forbitcoin:BTC -> (base|solana):USDCand any buy-side source-> lightning:BTC.refundAddressis required whenamountMode=exact_out.- If
Authorizationis included, sendX-Idempotency-Key. appFeesandaffiliateIdare currently supported only foramountMode=exact_inand whensourceChainordestinationChainisbase|solana.- Fee settlement chain is
sourceChainwhen source isbase|solana, otherwisedestinationChain. appFeesmax length is16.- Each
appFees[i].feeis fee bps (1..10000). - Sum of all app fee bps must be
<= 10000. affiliateIdmust match^[a-z0-9][a-z0-9_-]{0,63}$after trimming and lowercasing.- Use either
appFeesoraffiliateId, not both. affiliateIdrequires authenticated quote requests.slippageBpsdefaults to50when omitted.zeroconfEnabledis only used whensourceChain = bitcoinandamountMode = exact_in.- If omitted, it defaults to
true. - If the deployment does not have ZeroConf configured, the engine falls back to on-chain confirmations.
- If omitted, it defaults to
- For
destinationChain = lightning,recipientAddressmust be a BOLT11 invoice. Inexact_inmode, the invoice must be amountless (0-amount). Inexact_outmode, the invoice can be amountless or encode an amount matching the requestedamountin sats.
- Inline recipients:
appFees: [{ recipient: string, fee: number }]feeis fee bps per recipient (1..10000).
- Registry by id:
affiliateId: string- profile is managed through
PUT /v1/affiliates/:affiliateId - quote resolves recipient + fee bps from your partner-scoped profile
- Settlement asset is always USDC.
- Settlement chain is selected as:
sourceChainwhen source isbase|solana- otherwise
destinationChain(must bebase|solana)
- Execution point:
- If source is
base|solana, fees are deducted on the source-side USDC leg before bridge/swap continuation. - If source is not
base|solana, fees are deducted on the destination-side USDC payout leg.
- If source is
- For source native routes like
SOL -> BTCandETH -> BTC, fees are still deducted on the source-side USDC leg after ingress conversion (SOL|ETH -> USDC). - Quote math order:
- platform fee (
feeAmount) - optional sweep fee (
sweepFeeAmount, USDC-source routes only) - app fee allocation (
appFeeAmount,appFees) - 20% platform cut retained from each app fee (
appFeePlatformCutAmount); remaining 80% goes to the fee recipient - net amount proceeds to route execution
- platform fee (
- Flashnet retains 20% of each app/affiliate fee. The quote response shows the split per recipient:
amount(gross fee charged to the user),platformCutAmount(20% retained by Flashnet), andrecipientAmount(80% paid to the fee recipient). appFeesrecipients are validated against the settlement-chain address format.- For
affiliateId, the profile must have a recipient address for the quote settlement chain (baseand/orsolana).
depositAddressdepends onsourceChain:base|solana: chain address that receives the source assetspark: Spark address that receives BTC or USDBbitcoin: Bitcoin L1 addresslightning: BOLT11 invoice to pay
totalFeeAmountis returned whenfeeAssetisUSDCand equalsfeeAmount + appFeeAmount + sweepFeeAmount(when present).sweepFeeAmountis returned on some USDC-source routes when a sweep fee is configured, and is included intotalFeeAmount.appFeeAmountandappFeesare returned whenappFeesoraffiliateIdwas requested.appFeePlatformCutAmountis the sum of Flashnet’s 20% cut across all app fees.appFees[*].amountis the gross fee in settlement-chain USDC smallest units (what the user pays).appFees[*].platformCutAmountis Flashnet’s 20% cut of that fee.appFees[*].recipientAmountis the 80% paid to the fee recipient.appFees[*].affiliateIdis present when the quote usedaffiliateId.zeroconfEnabledis only present forsourceChain = bitcoin.lightningReceiveRequestIdis only present forsourceChain = lightningquotes.feeAssetisUSDBforBTC -> USDBquotes andUSDCotherwise.targetAmountOut,requiredAmountIn,maxAcceptedAmountIn, andinputBufferBpsare present for exact-out quotes.inputBufferBpsis currently2whenslippageBps=0, otherwise0.priceLockModeandlockedMinAmountOutare present for routes where a Flashnet min-out lock is enforced.
POST /v1/orchestration/submit
Create an order from a quote after you have initiated the source deposit. Headers:sourceChain.
Base/Solana sources (sourceChain = base|solana):
sourceAddress is optional but recommended. It is required when depositing to a shared address. When present, deposit verification requires the sender to match.
Spark sources (sourceChain = spark):
sourceSparkAddress is optional but recommended. It is required when depositing to a shared Spark address. When present, deposit verification requires the sender to match.
Bitcoin L1 sources (sourceChain = bitcoin):
bitcoinVout is optional. When omitted, the engine resolves it by scanning the transaction outputs for the one that pays the quote’s deposit address. You can still provide it explicitly if needed.
Lightning sources (sourceChain = lightning):
lightningReceiveRequestId can be omitted. When omitted, the API uses the value embedded in the quote.
The txHash field is validated per source chain:
- Base:
0x-prefixed 64-character hex string - Solana: Base58-encoded signature (64-90 characters)
- Bitcoin: 64-character hex transaction ID
- Spark: UUID format, 32-character hex, or 64-character token transaction hash
- Lightning: Automatically populated from the quote’s receive request ID
(sourceChain, sourceTxHash[, sourceTxVout]), submit returns the existing { orderId, status }.
POST /v1/orchestration/onramp
Combined quote and submit for Lightning sell flows. Creates a Lightning invoice and order in a single call. Designed for fiat onramp integrations where the user pays via Cash App. The source is alwayslightning:BTC. The amount field is BTC in sats.
Headers:
| Field | Required | Notes |
|---|---|---|
destinationChain | Yes | Target chain |
destinationAsset | Yes | Target asset |
recipientAddress | Yes | Address on the destination chain |
amount | Yes | BTC in sats (integer string) |
slippageBps | No | Default 50 |
appFees | No | Inline affiliate fees |
affiliateId | No | Registered affiliate ID |
paymentLinks.cashApp URL is a deeplink that opens Cash App to pay the Lightning invoice. On mobile, redirect the user to this URL. On desktop, display it as a QR code.
paymentLinks.shortUrl is a short redirect URL that 302s to the Cash App deeplink. Use this when sharing payment links in text messages, emails, or other contexts where the full Cash App URL is too long. The short URL is always present when PUBLIC_BASE_URL is configured on the server.
The Lightning invoice expires at expiresAt (2 minutes from creation). If the user doesn’t pay in time, create a new onramp order.
For the full integration guide with code examples, see Fiat Onramp.
GET /v1/orchestration/order
Look up a quote and its associated order by quote ID. Designed for submissionless flows where partners poll after creating a quote and directing a user to deposit. Returns the quote state alongside the order. When no order exists yet (deposit not detected),order is null and the quote’s expired field indicates whether the deposit window is still open.
Headers:
| Param | Required | Notes |
|---|---|---|
quoteId | Yes | Quote id (q_...) |
order object uses the same shape as GET /v1/orchestration/status, including optional swap, priceLock, reprice, paymentIntent, zeroconfOffer, feePlan, and feePayouts metadata when present.
Polling pattern for submissionless flows:
- Create a quote via
POST /v1/orchestration/quote. - Direct the user to deposit to
depositAddress. - Poll
GET /v1/orchestration/order?quoteId=q_...untilorderis non-null. - Once
orderappears, continue polling or switch to webhooks to track execution.
quote.expired is true and order is still null, the deposit window has closed. Expired quotes that receive a late deposit are repriced at live market rates and still create an order.
GET /v1/orchestration/status
Check an order’s current state. Authentication is optional:- Without
Authorization: returns a redacted order record. - With
Authorization: returns the full order record for your partner only.
| Param | Notes |
|---|---|
id | Order id (ord_...) |
quoteId | Quote id (q_...) |
txHash | Source transaction identifier (see order.sourceTxHash) |
txHash lookup returns the most recently created order with that sourceTxHash. For Bitcoin L1 deposits where multiple orders can share the same txid, prefer id from webhooks for exact attribution.
Possible order.status values:
processingconfirmingbridgingswappingawaiting_approvalrefundingdeliveringcompletedfailedrefunded
Authorization, the order object is the full public operation record. Without it, some fields are omitted.
amountIn and feeAmount reflect the actual processed deposit. When the on-chain deposit differs from the original quote, the engine updates these fields before execution. Any positive deposit amount is accepted. The stages array will include amount_reconciled when this adjustment occurred.
Depending on route and progress, the order can include:
flashnetRequestIdwhen a Flashnet swap has executedsparkTxHashwhen a Spark transfer, withdrawal, or Lightning action is createdswapmetadata when a Flashnet swap leg has been recordedpriceLock,reprice, andpaymentIntentmetadata for locked/approval-required flowszeroconfOfferwhen a ZeroConf offer has been generated for a Bitcoin L1 deposit (see ZeroConf offer fields)feePlanwhen quote-levelappFeesoraffiliateIdwas requestedfeePayoutsas affiliate and recipient payout legs are executedfeePayouts.entries[*].roleisapp_feeorrecipient_payoutfeePayouts.entries[*].affiliateIdis present for app-fee entries derived fromaffiliateIdfeePayouts.entries[*].legisfull,instant, orholdbackfor routes that execute in multiple legs
GET /v1/orchestration/history
List your orders filtered byrecipientAddress.
Headers:
| Param | Required | Notes |
|---|---|---|
address | Yes | Recipient address (Spark address, Bitcoin address, Lightning invoice, or Base/Solana address depending on the route) |
status | No | Exact match on the order status |
limit | No | Default 50, max 200 |
offset | No | Default 0 |
GET /v1/orchestration/status, including optional swap, priceLock, reprice, paymentIntent, and zeroconfOffer metadata when present.