> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Lifecycle

> Understand how Orchestra quotes become orders, track status transitions, and handle deposit flexibility and market-move refunds.

## How do quotes become orders?

A quote is a priced intent with a 2-minute TTL. Call `POST /v1/orchestration/quote` to get deposit instructions and pricing. A quote does not create an order.

An order is created when you call `POST /v1/orchestration/submit` with the quote ID and a funded deposit proof. The order tracks execution from deposit through delivery.

Orders can also be created automatically via submissionless flows. When a deposit arrives at a quote's deposit address, the system detects the deposit via webhooks (Helius for Solana, Blockdaemon for Bitcoin) or polling (Spark ingress scan) and creates the order without requiring an explicit `/submit` call. Late deposits (arriving after quote expiry) are always accepted and repriced at the live market rate at detection time; execution is still bounded by the quote's `slippageBps`.

For submissionless flows, use `GET /v1/orchestration/order?quoteId=...` to poll for order creation. This endpoint returns both the quote state and the order (or `null` if no deposit has been detected yet). See [API: Quotes and Orders](/products/orchestration/api/quotes-and-orders#get-v1orchestrationorder) for the full response shape.

<Info>
  `GET /v1/orchestration/status?quoteId=...` returns 404 for quotes that have not been submitted. Use `GET /v1/orchestration/order` instead when you need to poll before the order exists.
</Info>

## Status state machine

Every order moves through a subset of these statuses. The allowed transitions from each status are:

| From                | Allowed transitions                                                                                                                  |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `processing`        | confirming, bridging, swapping, awaiting\_approval, paused, refunding, delivering, completed, failed, expired, unfulfilled, refunded |
| `confirming`        | bridging, swapping, refunding, paused, delivering, completed, failed, expired, refunded                                              |
| `bridging`          | swapping, paused, delivering, completed, failed, refunded                                                                            |
| `swapping`          | awaiting\_approval, paused, refunding, bridging, delivering, completed, failed, refunded                                             |
| `awaiting_approval` | processing, confirming, swapping, refunding, paused, failed, refunded                                                                |
| `paused`            | processing, failed                                                                                                                   |
| `refunding`         | paused, refunded, failed                                                                                                             |
| `delivering`        | confirming, paused, refunding, completed, failed, refunded                                                                           |
| `completed`         | (terminal)                                                                                                                           |
| `failed`            | (terminal)                                                                                                                           |
| `expired`           | (terminal)                                                                                                                           |
| `unfulfilled`       | confirming, bridging, swapping, delivering, completed                                                                                |
| `refunded`          | (terminal)                                                                                                                           |

<Info>
  `awaiting_approval` is used only for [ZeroConf](/products/orchestration/zeroconf) offer acceptance. Market-move refunds happen automatically from `swapping` to `refunding` without partner action.
</Info>

<Info>
  `paused` is an internal operator-review state. Public status responses, SSE, and webhook payloads show paused orders as `processing` until the order resumes or moves to a partner-visible final state.
</Info>

### Typical happy paths

**Stablecoin to BTC:**

`processing` -> `bridging` -> `swapping` -> `delivering` -> `completed`

**BTC to Stablecoin (Spark source):**

`processing` -> `swapping` -> `bridging` -> `delivering` -> `completed`

**BTC to Stablecoin (Bitcoin L1 source, no ZeroConf):**

`processing` -> `confirming` -> `swapping` -> `bridging` -> `delivering` -> `completed`

**BTC to Stablecoin (Bitcoin L1 source, ZeroConf offer):**

`processing` -> `awaiting_approval` -> `processing` -> `swapping` -> `bridging` -> `delivering` -> `completed`

**Refund on market move:**

`processing` -> `swapping` -> `refunding` -> `refunded`

**Lightning to direct BTC (Spark or Bitcoin L1):**

`processing` -> `confirming` -> `delivering` -> `completed`

Hard terminal statuses are `completed`, `failed`, `expired`, and `refunded`. `unfulfilled` stops automatic execution, but can resume if a late deposit is detected.

<Info>
  Not every status appears in every route. A Spark-source sell may skip `confirming` and `bridging`. Track progress via webhooks or poll `GET /v1/orchestration/status` rather than assuming a fixed sequence.
</Info>

## Field mapping

Fields shift names and semantics between the quote response and the order (status/webhook payload).

| Concept                  | Quote response            | Order status / Webhook         | Notes                                                                                                            |
| ------------------------ | ------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Input amount             | `amountIn`                | `amountIn`                     | May differ from quote if actual deposit is over/under                                                            |
| Output amount            | `estimatedOut`            | `amountOut`                    | Quote: estimated. Order: actual. `null` until delivery completes                                                 |
| Platform fee             | `feeAmount`               | `feeAmount`                    | Recalculated if actual deposit differs from quote                                                                |
| Stable rounding retained | `roundingFeeAmount`       | `roundingFeeAmount`            | Stablecoin surplus retained instead of delivered. Used when output is capped to a whole-cent or exact-out target |
| Total fees               | `totalFeeAmount`          | --                             | Only on quote response when USDC fee asset                                                                       |
| App fees                 | `appFeeAmount`            | --                             | Only on quote when appFees/affiliateId requested                                                                 |
| App fee platform cut     | `appFeePlatformCutAmount` | --                             | Flashnet's 20% cut of app fees. Only on quote when appFees/affiliateId requested                                 |
| Deposit target           | `depositAddress`          | `depositAddress`               | Same value carried from quote to order                                                                           |
| Quote reference          | `quoteId`                 | `quoteId`                      | Order references its source quote                                                                                |
| Order reference          | --                        | `id` (order)                   | Only exists after submit                                                                                         |
| Destination tx           | --                        | `destination.txHash` (webhook) | Populated on delivery                                                                                            |

<Info>
  When the actual deposit differs from the quoted amount, the engine updates `amountIn` and `feeAmount` on the order before proceeding. An `amount_reconciled` stage is recorded. Webhook payloads and status responses reflect the updated values.
</Info>

## What happens if the deposit amount differs from the quote?

Deposits do not need to match the quoted `amountIn` exactly. Any positive deposit is accepted. The engine adjusts `amountIn` and fees to reflect the actual deposit before execution. Slippage protection is enforced at swap execution time against the quote's `slippageBps`.

* **Underpayment**: accepted for exact-in orders. Smaller deposits produce less price impact, so the per-unit rate stays the same or improves. Exact-out orders that receive less than `requiredAmountIn` refund automatically with `exact_out_insufficient_input`.
* **Overpayment**: accepted for exact-in orders. Exact-out orders that receive more than `maxAcceptedAmountIn` refund automatically with `exact_out_input_above_max`.
* **Market moved past slippage**: if the pool price shifts past `slippageBps` between deposit and execution, the order refunds automatically with `slippage_exceeded`. No partner action is required.

Lightning deposits are excluded from flexible amounts since invoices are fixed-amount by protocol design.

## Market moves and refunds

Orders that cannot execute cleanly refund without partner involvement. The relevant `errorCode` values on the order record are:

* `slippage_exceeded`: pool moved past `slippageBps` between deposit and execution
* `exact_out_insufficient_input`: exact-out deposit below `requiredAmountIn`
* `exact_out_input_above_max`: exact-out deposit above `maxAcceptedAmountIn`
* `exact_out_target_not_met`: pool couldn't produce `targetAmountOut` at execution time

All refund paths emit `order.refunding` followed by `order.refunded`. Partners should render these as normal refund outcomes. There is no accept/decline endpoint. Once the deposit lands, execution proceeds automatically or refunds. See [Error codes](/products/orchestration/api/error-codes#order-lifecycle-error-codes) for the full list.

## What are the effective limits?

| Parameter        | Value                                    |
| ---------------- | ---------------------------------------- |
| Minimum          | \$1 equivalent                           |
| Maximum          | \$100,000 equivalent                     |
| BTC swap minimum | 1,000 sats                               |
| Platform fee     | Custom pricing based on route and volume |

<Warning>
  Some USDC-source routes include a sweep fee (`sweepFeeAmount` in the quote response). This creates an effective minimum higher than \$1 because the sweep fee is deducted from the input before execution. Check the quote response for `sweepFeeAmount` on affected routes.
</Warning>

<Info>
  For `lightning:BTC -> bitcoin:BTC`, the final on-chain withdrawal also pays the network withdrawal fee quoted at delivery time. That fee is separate from the platform fee shown on the quote or order.
</Info>

## Next steps

* [Quickstart](/products/orchestration/integration)
* [ZeroConf](/products/orchestration/zeroconf)
* [API: Quotes and Orders](/products/orchestration/api/quotes-and-orders)
* [API: Approval Flows](/products/orchestration/api/approval-flows) (ZeroConf only)
* [API: Error codes](/products/orchestration/api/error-codes)
