---
name: Flashnet
description: Use when building payment and swap flows across Bitcoin, stablecoins, and supported networks. Reach for this skill when integrating deposit-to-delivery workflows, handling multi-chain routing, managing Bitcoin L1/Lightning/Spark deposits, or building wallets, exchanges, commerce platforms, and payouts that need unified cross-chain settlement.
metadata:
    mintlify-proj: flashnet
    version: "1.0"
---

# FlashNet Orchestra Skill

## Product summary

FlashNet Orchestra is a unified async API for routing payments and swaps across Bitcoin (L1, Lightning, Spark), stablecoins, and supported networks (Solana, EVM chains, Tron, TON, and others). Agents use Orchestra to build deposit-to-delivery flows without operating bridges, swap venues, or Bitcoin infrastructure. Base URL: `https://orchestration.flashnet.xyz`. Key files: API keys (server `fn_...` and client `fnp_...` prefixes), webhook secrets, and idempotency keys. CLI equivalent: REST API with OpenAPI at `/docs` and `/openapi.json`. Primary docs: https://docs.flashnet.xyz/products/orchestration/overview.

## When to use

Reach for this skill when:
- Building a wallet, exchange, or commerce platform that needs to route payments across chains
- Integrating Bitcoin deposits (L1, Lightning, or Spark) into a stablecoin or asset flow
- Creating reusable deposit addresses that auto-convert to a fixed destination
- Handling exact-out payments where the recipient must receive a specific amount
- Implementing fiat onramps via Lightning invoices
- Building shareable payment links with fixed stablecoin outputs
- Tracking order status through async execution (deposit → bridge → swap → delivery)
- Handling repricing when deposits arrive late or market conditions change
- Managing ZeroConf (instant Bitcoin L1 credit) offers
- Integrating affiliate or app fees into payment flows

Do not use Orchestra for: direct wallet-to-wallet transfers without conversion, non-payment use cases, or operations that require synchronous execution.

## Quick reference

### API endpoints (base: `https://orchestration.flashnet.xyz`)

| Endpoint | Method | Auth | Purpose |
|----------|--------|------|---------|
| `/v2/orchestration/routes` | GET | None | Discover live source/destination pairs, contract addresses, decimals |
| `/v1/orchestration/estimate` | GET | None | Show price preview (no quote created) |
| `/v1/orchestration/quote` | POST | Server/Client | Create priced intent, allocate deposit address (2-min TTL) |
| `/v1/orchestration/submit` | POST | Server/Client | Create order from funded quote |
| `/v1/orchestration/onramp` | POST | Server/Client | Create Lightning invoice order in one call |
| `/v1/orchestration/status` | GET | Server/Client | Poll order status |
| `/v1/orchestration/order` | GET | Server/Client | Poll for order creation (submissionless flows) |
| `/v1/sse/operations/:id` | GET | Server/Client | Stream order status via EventSource |
| `/v1/webhooks` | POST | Server | Register webhook endpoint |
| `/v1/standing-deposit-addresses/{ref}` | PUT/GET/PATCH | Server | Create/retrieve/pause permanent deposit addresses |
| `/v1/accumulation-addresses` | POST | Server/Client | Create reusable deposit address (any chain → Spark BTC/USDB) |
| `/v1/liquidation-addresses` | POST | Server/Client | Create reusable deposit address (Bitcoin L1 → any chain) |

### Authentication

- **Server key** (`fn_...`): Secret, full access, use on backend only
- **Client key** (`fnp_...`): Public, scope-gated, safe for SDKs and browser code
- Pass as `Authorization: Bearer <key>`
- Client keys require `X-Read-Token` header (returned in submit/onramp response) to read orders they created

### Required headers for mutations

- `Authorization: Bearer fn_...` or `Bearer fnp_...`
- `X-Idempotency-Key: <unique-string>` (partner-scoped, prevents duplicate processing)
- `Content-Type: application/json`

### Amount format

- Integer strings in smallest units (no floats)
- Read decimals from `GET /v2/orchestration/routes` for each asset
- Example: USDC (6 decimals) = `"100000000"` for $100

### Deposit address types

| Type | Reusable | Per-deposit | TTL | Use case |
|------|----------|-------------|-----|----------|
| Quote deposit | No | Yes | 2 min | Quote/submit flow |
| Accumulation | Yes | No | Permanent | Auto-convert any chain → Spark BTC/USDB |
| Liquidation | Yes | No | Permanent | Auto-convert Bitcoin L1 → any chain |
| Standing | Yes | No | Permanent | Immutable destination, deposit tracking, refunds |

### Order status state machine (key transitions)

```
processing → confirming → bridging → swapping → delivering → completed
                                ↓
                        awaiting_approval (ZeroConf)
                                ↓
                        processing (after accept/decline)

Any status → refunding → refunded (automatic on market move or validation failure)
Any status → failed (terminal)
```

### Webhook events

Emitted on status transitions: `order.processing`, `order.confirming`, `order.bridging`, `order.swapping`, `order.awaiting_approval`, `order.refunding`, `order.delivering`, `order.completed`, `order.failed`, `order.unfulfilled`, `order.refunded`.

Signature verification: `HMAC_SHA256(secret, timestamp + "." + raw_body)` where timestamp is from `X-Flashnet-Timestamp` header.

## Decision guidance

### When to use quote/submit vs other flows

| Scenario | Use |
|----------|-----|
| Need per-transaction price control, exact-out, or any live route | Quote/Submit |
| User starts from Lightning balance, want one API call | Onramp (`POST /v1/orchestration/onramp`) |
| Shareable "pay me $X" links via Lightning | Pay Links |
| Auto-convert inbound stablecoins to BTC on Spark | Accumulation addresses |
| Auto-convert Bitcoin L1 deposits to any asset | Liquidation addresses |
| Permanent addresses across multiple source chains, deposit tracking | Standing deposit addresses |

### When to use server key vs client key

| Condition | Use |
|-----------|-----|
| Code runs on your backend (server, VPC, private container) | Server key (`fn_...`) |
| Code ships in client-side bundle (browser, mobile app, open-source SDK) | Client key (`fnp_...`) |
| Need to manage webhooks, affiliates, or transaction history | Server key only |
| Need to read orders created by other keys | Server key only |

### When to use exact-in vs exact-out

| Mode | Sender pays | Receiver gets | Use case |
|------|-------------|---------------|----------|
| Exact-in (default) | Fixed input amount | Variable output (subject to slippage) | "I want to send $100 USDC" |
| Exact-out | Variable input (within bounds) | Fixed output amount | "I want to receive exactly 1 BTC" |

## Workflow

### Standard quote/submit flow

1. **Discover routes**: Call `GET /v2/orchestration/routes` once and cache. Reuse to validate pairs and read decimals.
2. **Show price preview**: Call `GET /v1/orchestration/estimate` (no auth) on every amount/route change while user browses.
3. **Create quote**: When user commits, call `POST /v1/orchestration/quote` with `Authorization` and `X-Idempotency-Key`. Store `quoteId` and `depositAddress`. Quote expires in 2 minutes.
4. **Send deposit**: Direct user to send exactly `amountIn` of source asset to `depositAddress`. Deposit format depends on source chain (EVM tx hash, Solana signature, Bitcoin txid+vout, Spark transfer ID, or Lightning invoice).
5. **Submit deposit**: Call `POST /v1/orchestration/submit` with `quoteId` and source transaction proof. Returns `orderId` and `readToken` (for client keys).
6. **Track order**: Use webhooks (preferred) or poll `GET /v1/orchestration/status?id=<orderId>`. For client keys, include `X-Read-Token` header.
7. **Persist data**: Store `quoteId`, `orderId`, source tx identifier, `order.status`, `order.error`, and optional fields (`paymentIntent`, `zeroconfOffer`, `refund`).

### Reusable address flow (accumulation or liquidation)

1. **Create address**: Call `POST /v1/accumulation-addresses` or `POST /v1/liquidation-addresses` with destination chain/asset and recipient address.
2. **Display address**: Return the address from the response. It is deterministic and permanent for that destination.
3. **Detect deposit**: Register a webhook. When deposit arrives, order is created automatically (no `/submit` call needed).
4. **Track order**: Use webhooks or poll `GET /v1/orchestration/status?id=<orderId>`.

### Standing deposit address flow

1. **Create instruction**: Call `PUT /v1/standing-deposit-addresses/{ref}` with customer reference, destination chain/asset, and recipient. Returns address map for enabled source chains.
2. **Display addresses**: Show returned addresses to customer. They are permanent for this reference.
3. **Register webhook**: Ensure partner webhook is registered to receive deposit notifications.
4. **Detect deposit**: Webhook fires when deposit arrives. Order is created automatically.
5. **Track deposits**: Call `GET /v1/standing-deposit-addresses/{ref}/deposits` to list observed deposits and their order IDs.
6. **Handle refunds**: Call `POST /v1/standing-deposit-addresses/{ref}/resolve` to request refund for a specific deposit.

### ZeroConf (instant Bitcoin L1 credit) flow

1. **Monitor for awaiting_approval**: When order status is `awaiting_approval` AND `zeroconfOffer.status` is `pending`, a ZeroConf offer is available.
2. **Present offer to user**: Show the offer terms (instant credit amount, fee, etc.).
3. **Accept or decline**: Call `POST /v1/orchestration/approval-flows/accept` or `decline` with `orderId`.
4. **Resume processing**: Order moves back to `processing` and continues execution.

## Common gotchas

- **Never reuse quote deposit addresses**: Each quote generates a fresh deposit address. Sending a second deposit to an expired quote's address will be repriced at live rates and may refund if it violates exact-out bounds.
- **Idempotency key scope is per-partner, per-endpoint**: Reusing the same key on different endpoints or with different request bodies causes `409 idempotency_conflict`. Use unique keys per action.
- **Late deposits are repriced**: Deposits arriving after quote expiry are accepted but repriced at live market rate. Execution is still bounded by the quote's `slippageBps`, so late deposits may refund if market moved too far.
- **Client keys need read-tokens**: When using a client key to submit an order, the response includes a `readToken`. You must pass this token in the `X-Read-Token` header (or `?readToken=` query param) to read that order. Without it, you get `403 read_token_required`.
- **Exact-out requires refundAddress**: Exact-out orders must include a `refundAddress` in the quote request. Without it, validation fails.
- **Amounts are integer strings, not floats**: Send `"100000000"` not `100000000` or `100.0`. Read decimals from `/routes` for each asset.
- **Webhook signatures include timestamp**: Signature is `HMAC_SHA256(secret, timestamp + "." + raw_body)`. The timestamp comes from the `X-Flashnet-Timestamp` header, not the JSON payload. Verify timing-safe to prevent timing attacks.
- **Webhook delivery is at-least-once**: The same event may be delivered multiple times. Make your handler idempotent using `(data.id, event, data.updatedAt)` as the dedup key, not the signature timestamp (it changes on retry).
- **Standing addresses are immutable**: To change the destination, create a new reference. You cannot modify an existing instruction's destination.
- **Accumulation/liquidation addresses are deterministic**: Creating the same configuration twice returns the same address. This is intentional for reusability, but means you cannot create multiple addresses for the same destination.
- **Sweep fees on USDC routes**: Some USDC-source routes include a `sweepFeeAmount` in the quote response. This is deducted from input before execution, raising the effective minimum. Check the quote response.
- **Bitcoin L1 minimums**: 5,000 sats for swap input (deposits), 10,000 sats for delivery. Spark deposits: 1,200 sats minimum.
- **Lightning invoices are single-use**: A destination Lightning invoice can only settle once. Reusing an invoice causes `duplicate_lightning_invoice` error.
- **Do not hardcode routes or limits**: Routes and amount bounds change at runtime. Always call `/routes` and `/limits` to discover current state.
- **Refund address for exact-in**: While optional for exact-in, supply a `refundAddress` whenever possible. Without one, Orchestra can only refund to a detected source address if it is safe (not an exchange or shared address).

## Verification checklist

Before submitting work:

- [ ] Verified API key is correct type (server `fn_...` for backend, client `fnp_...` for browser/SDK)
- [ ] All mutation requests include `X-Idempotency-Key` header with unique value
- [ ] Amounts are integer strings in smallest units (read decimals from `/routes`)
- [ ] Quote requests include `Authorization` and `X-Idempotency-Key` if they will be submitted
- [ ] Webhook endpoint is registered and secret is stored securely
- [ ] Webhook signature verification uses `timestamp + "." + raw_body` (not just body)
- [ ] Webhook handler is idempotent (uses `(data.id, event, data.updatedAt)` dedup key)
- [ ] Client key reads include `X-Read-Token` header or `?readToken=` query param
- [ ] Exact-out orders include `refundAddress` in quote request
- [ ] Deposit address is never reused after quote expiry or submission
- [ ] Order status is tracked via webhooks (preferred) or polling, not assumed to follow a fixed sequence
- [ ] Refund scenarios are handled (automatic on market move, no partner action needed)
- [ ] Late deposits are expected and handled (repriced at live rates)
- [ ] Standing address references are stable and customer-scoped (not generated per request)
- [ ] Persisted data includes `quoteId`, `orderId`, source tx identifier, and optional workflow fields

## Resources

- **Comprehensive page navigation**: https://docs.flashnet.xyz/llms.txt
- **API Overview & Authentication**: https://docs.flashnet.xyz/products/orchestration/api/overview
- **Quickstart (Quote/Submit Flow)**: https://docs.flashnet.xyz/products/orchestration/integration
- **Order Lifecycle & Status Machine**: https://docs.flashnet.xyz/products/orchestration/order-lifecycle
- **Supported Routes Discovery**: https://docs.flashnet.xyz/products/orchestration/routes
- **Webhooks & Signature Verification**: https://docs.flashnet.xyz/products/orchestration/webhooks
- **Client Keys & Scopes**: https://docs.flashnet.xyz/products/orchestration/api/client-keys
- **Error Codes**: https://docs.flashnet.xyz/products/orchestration/api/error-codes

---

> For additional documentation and navigation, see: https://docs.flashnet.xyz/llms.txt