expiresAt for the decision deadline; offers currently last five minutes from creation, not receipt.
Mechanism
Eligibility depends on partner and route policy and an available Spark plan. An offer is not guaranteed. Under the default ordinary-order policy,zeroconfOffer.status: "pending" moves the order to awaiting_approval. Acceptance starts the credit claim and returns processing; the delivery pipeline still has to run. A configured legacy policy can auto-accept ordinary offers. Standing deposits always require explicit consent.
Declining or expiry falls back to 1 confirmation. Accepted credit is single-leg: confirmation releases no extra amount.
Scope
- Source chain
bitcoin,exact_inonly. Exact-out orders are always confirmation-based. - Read the order or standing deposit for an offer; quote responses do not predict one.
- The credited amount must meet the 1,000-sat execution floor.
Ordinary orders
Act only whenstatus is awaiting_approval and zeroconfOffer.status is pending. Accept the offer:
Replace
SERVER_KEY with your fn_... key. Use a new X-Idempotency-Key for each operation and reuse it when retrying that same request. Amounts are integer strings in the asset’s smallest unit: "100000" is 0.001 BTC; "50000000" is 50 USDC on Base. Read each asset’s decimals from /routes.409 expired: deadline passed.409 conflict: order state changed; refresh.400 invalid_state: order or offer is not awaiting a decision.
Offer fields
version: schema version,1.status:pending,accepted,declined,expired, orconfirmed(the transaction reached 1 confirmation before a decision).quoteId,sparkAddress: Spark quote and credit destination.txid,vout: the L1 output being credited.depositSats: gross output value.instantSats: amount credited on accept.feeSats: Spark’s static-deposit fee, not a Flashnet fee.expiresAt: authoritative decision deadline.offeredAt,resolvedAt: offer and decision timestamps.sparkTxid: Spark transaction once the claim runs.
depositSats = instantSats + feeSats. Read feeSats from each offer; it changes per deposit. An order whose zeroconfOffer is { status: "denied", deniedAt } received no offer and has nothing to act on.
Standing deposits
Standing offers require partner allowlisting and explicit deposit-scoped acceptance, even when legacy auto-accept is enabled. The public shape is separate from the ordinary order offer:depositSats = creditSats + feeSats. Provider-plan fields are not returned. Confirmation can supersede an offer.
Send POST /v1/standing-deposit-addresses/{ref}/deposits/{depositId}/zeroconf/accept or /decline with { "offerId": "OFFER_ID" }, a server key, and X-Idempotency-Key. Accept returns 202 { deposit }; decline returns 200 { deposit }. Use the offer’s id; no order need exist yet.
On 409 standing_zeroconf_offer_conflict, refresh the deposit. Retry an uncertain decision with the same idempotency key. Without acceptance, processing waits for confirmation.