> ## 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.

# ZeroConf

> Bitcoin instant credit

ZeroConf lets eligible Bitcoin L1 deposits continue before the transaction reaches its first block confirmation.

## What does ZeroConf do?

When a Bitcoin L1 deposit is detected, the engine asks Spark for an instant static-deposit quote. If Spark returns a 0-conf fulfillment plan, Orchestra creates a ZeroConf offer and moves the order to `awaiting_approval`. Partners accept the offer to continue immediately, or decline it to wait for the normal confirmed path.

## How are confirmations handled?

| Scenario                                           | Confirmations required |
| -------------------------------------------------- | ---------------------- |
| ZeroConf offer accepted                            | 0 (instant)            |
| ZeroConf offer declined                            | 1                      |
| ZeroConf offer expired (no response)               | 1                      |
| Spark requires confirmation or no offer is created | 1                      |

## What is the offer flow?

<Steps>
  <Step title="Create a Bitcoin L1 quote">
    Create an exact-in quote with `sourceChain=bitcoin`. The quote response returns a Bitcoin L1 `depositAddress`. It does not include a ZeroConf offer.
  </Step>

  <Step title="Deposit detected">
    After the Bitcoin transaction is broadcast and detected, the engine evaluates the specific UTXO for ZeroConf eligibility.
  </Step>

  <Step title="Spark returns a plan">
    If Spark returns a 0-conf plan, the engine stores a pending `zeroconfOffer` and moves the order to `awaiting_approval`. If Spark requires confirmation, the order waits for 1 block.
  </Step>

  <Step title="Accept or decline">
    Call `POST /v1/orchestration/zeroconf/accept` for instant credit, or `POST /v1/orchestration/zeroconf/decline` to wait for 1 confirmation. If you do not respond before `expiresAt`, the offer expires and the engine waits for 1 confirmation.
  </Step>

  <Step title="Execution continues">
    After acceptance (instant credit) or confirmation (1 block), the order proceeds through swapping, bridging, and delivery.
  </Step>
</Steps>

## What fields are in a ZeroConf offer?

When present, `order.zeroconfOffer` contains:

| Field          | Type           | Description                                                                          |
| -------------- | -------------- | ------------------------------------------------------------------------------------ |
| `status`       | string         | `pending`, `accepted`, `declined`, `expired`, or `confirmed`                         |
| `quoteId`      | string         | ZeroConf quote identifier                                                            |
| `depositSats`  | string         | Total BTC deposited (sats)                                                           |
| `instantSats`  | string         | Amount credited instantly on acceptance                                              |
| `holdbackSats` | string         | Amount reserved for later confirmed credit. Current generated offers use `"0"`       |
| `feeSats`      | string         | Difference between `depositSats` and `instantSats` from Spark's static-deposit quote |
| `expiresAt`    | string         | Offer expiry (ISO 8601)                                                              |
| `offeredAt`    | string         | When the offer was generated                                                         |
| `resolvedAt`   | string or null | When accepted, declined, or expired. `null` while pending                            |

The `confirmed` status means the Bitcoin transaction reached 1 confirmation before the offer was resolved, bypassing the approval window entirely.

`feeSats` is not the Flashnet orchestration platform fee. Platform pricing stays in the normal quote and order fields such as `feeBps`, `feeAmount`, and `totalFeeAmount`.

Read `feeSats` from each offer. Do not hard-code a fixed percentage or fixed sat amount.

## How do I accept or decline an offer?

Accept (instant credit):

```bash theme={null}
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/zeroconf/accept" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: zeroconf:accept:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orderId": "ord_..."}'
```

Decline (wait for 1 confirmation):

```bash theme={null}
curl -sS -X POST "https://orchestration.flashnet.xyz/v1/orchestration/zeroconf/decline" \
  -H "Authorization: Bearer fn_..." \
  -H "X-Idempotency-Key: zeroconf:decline:YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orderId": "ord_...", "reason": "Optional reason"}'
```

## When does ZeroConf apply?

* ZeroConf applies to eligible `sourceChain=bitcoin` exact-in orders after the Bitcoin transaction is detected.
* Exact-out (`amountMode=exact_out`) uses confirmation-based processing and does not use ZeroConf.
* Quote responses do not predict whether an offer will be created. The decision depends on the detected UTXO and Spark's fulfillment plan.
* If Spark does not return a 0-conf plan, the engine falls back to the confirmed path without a partner action.

## How does ZeroConf work with liquidation addresses?

Liquidation addresses use Bitcoin L1 deposits and are ZeroConf-eligible. When Spark returns a 0-conf plan, each deposit generates a ZeroConf offer requiring partner resolution via webhook and API call. If no offer is created, the deposit continues on the confirmed path.

Some deployments require ZeroConf to be configured for liquidation address provisioning. If address creation returns a configuration error, contact your Flashnet operator.

See [reusable addresses](/products/orchestration/reusable-addresses#liquidation-addresses) for setup.

## Next steps

* [Order Lifecycle](/products/orchestration/order-lifecycle)
* [API: Approval Flows](/products/orchestration/api/approval-flows)
* [Reusable Addresses](/products/orchestration/reusable-addresses)
