Skip to main content
Orchestra is async. You request a quote, accept a deposit, submit it, then track the order to completion. Base URL: https://orchestration.flashnet.xyz

The Minimal Flow

1

Create a webhook endpoint

Register a webhook endpoint and store the returned secret.
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/webhooks" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: webhook:create:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://yourapp.example.com/flashnet/webhooks"}'
Verify inbound webhooks using X-Flashnet-Signature and the raw request body. See Webhooks.
2

Request a quote

Quotes expire 30 minutes after creation.Quote requests that you intend to submit must include Authorization and X-Idempotency-Key.Example (exact-in, default mode): buy BTC on Spark with USDC on Base.
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/quote" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: quote:create:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceChain": "base",
    "sourceAsset": "USDC",
    "destinationChain": "spark",
    "destinationAsset": "BTC",
    "amount": "100000000",
    "recipientAddress": "spark1...",
    "slippageBps": 50
  }'
3

Send the deposit

Send the source asset to depositAddress.The deposit instruction depends on the route:
  • Base/Solana source (sourceChain = base|solana): depositAddress is a chain address that receives the source asset.
  • Spark source (sourceChain = spark): depositAddress is a Spark address.
  • Bitcoin source (sourceChain = bitcoin): depositAddress is a Bitcoin L1 address.
  • Lightning source (sourceChain = lightning): depositAddress is a BOLT11 invoice.
For USDC routes, send exactly amountIn.
4

Submit the deposit

Submitting creates an order. Processing is async.submit requires:
  • Authorization: Bearer fn_...
  • X-Idempotency-Key
USDC deposit submit:
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/submit" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: submit:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "q_...",
    "txHash": "0x...",
    "sourceAddress": "0x..."
  }'
Submit shape depends on the quote sourceChain. Examples:
{ "quoteId": "q_...", "sparkTxHash": "spark_transfer_id_or_token_tx_hash" }
{ "quoteId": "q_...", "bitcoinTxid": "<txid>", "bitcoinVout": 0 }
{ "quoteId": "q_...", "lightningReceiveRequestId": "<id>" }
See API Reference for the full request shapes and optional fields.
5

Track the order

Preferred: use webhooks.Fallback: poll status.
curl -sS "https://orchestration.flashnet.xyz/v1/orchestration/status?id=ord_..."
Treat every webhook delivery as at least once.

Picking a Route

Advanced Workflows

Exact-out mode (amountMode=exact_out) is currently supported only for bitcoin:BTC -> (base|solana):USDC.Quote request:
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/quote" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: quote:exact-out:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceChain": "bitcoin",
    "sourceAsset": "BTC",
"destinationChain": "base",
"destinationAsset": "USDC",
"amount": "100000000",
"amountMode": "exact_out",
"recipientAddress": "0xYourBaseUsdcAddress",
"refundAddress": "bc1qyourrefundaddress...",
"slippageBps": 0
}'
For exact-out quotes, the response adds:
  • targetAmountOut
  • requiredAmountIn
  • maxAcceptedAmountIn
  • inputBufferBps
Deposit guidance:
  • Use requiredAmountIn as the primary send amount.
  • Stay at or below maxAcceptedAmountIn for auto-acceptance.
  • If actual input is below requiredAmountIn, above maxAcceptedAmountIn, or if latest expected output cannot satisfy the target, the order moves to awaiting_approval.
Affiliate fees let you allocate an app fee to one or more recipients on supported routes.Two models:
  • Inline recipients: appFees: [{ recipient: string, fee: number }]
  • Registry by id: affiliateId: string with profiles managed by PUT|GET|DELETE /v1/affiliates/*
Exact-in affiliate-fee example (spark:BTC -> solana:USDC):
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/quote" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: quote:appfees:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sourceChain": "spark",
    "sourceAsset": "BTC",
"destinationChain": "solana",
"destinationAsset": "USDC",
"amount": "100000",
"recipientAddress": "So1RecipientAddress...",
"appFees": [
  { "recipient": "So1AffiliateOne...", "fee": 100 },
  { "recipient": "So1AffiliateTwo...", "fee": 50 }
]
}'
Optional registry setup:
curl -sS -X PUT "https://orchestration.flashnet.xyz/v1/affiliates/swapkit" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: affiliate:swapkit:create:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "settlementChain": "solana",
    "recipientAddress": "So1AffiliateTreasury...",
    "feeBps": 100
  }'
Current app-fee constraints:
  • amountMode must be exact_in.
  • sourceChain or destinationChain must be base or solana.
  • Use either appFees or affiliateId, not both.
  • affiliateId requires authenticated quote requests.
  • appFees recipient addresses must match the fee-settlement chain (sourceChain when it is base|solana, otherwise destinationChain).
  • For affiliateId, the stored profile must have a recipient address for the quote settlement chain.
If the order status is awaiting_approval, inspect:
  • order.reprice
  • order.priceLock
  • order.paymentIntent
Approve and continue execution:
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/reprice/approve" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: reprice:approve:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "ord_...",
    "approvedMinAmountOut": "99500000"
  }'
Reject and fail:
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/reprice/reject" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: reprice:reject:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "ord_...",
    "reason": "Optional reason"
  }'
Reject and refund BTC (Bitcoin source orders):
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/reprice/refund" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: reprice:refund:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "ord_...",
    "reason": "Optional reason",
    "refundAddress": "bc1qoptionaloverride..."
  }'
reprice/refund returns status=refunding. Final status is refunded (or failed if refund execution fails).
Persist these identifiers:
  • quoteId
  • orderId
  • the source transaction identifier you submitted (txHash, bitcoinTxid + bitcoinVout, Spark transfer id, or Lightning receive request id)
Persist these optional workflow fields for approval/refund flows:
  • order.status
  • order.reprice
  • order.paymentIntent
  • order.refund

Next Steps