0Bit Documentation

Quotes and pricing

Design 0Pools quote UX around indicative quotes, firm quote locks, expiry, spread, fees, and execution.

Quotes are the product contract of 0Pools. They turn a volatile fiat/stablecoin market into a bounded partner-visible offer: rate, fees, side, amount, network, delivery target, and expiry.

Quote ladder

Indicative vs firm

Quote typePersistedExecutableBest for
indicativeNoNoLive price preview while the user edits.
firmYesYes, onceThe exact terms the user accepts.

Do not transact an indicative quote. It has no quoteId and no inventory lock.

What the quote locks

Locked fieldWhy
Pool idPrevents switching route after user acceptance.
SideDefines amount semantics.
Fiat and crypto currenciesDefines pair.
AmountsPrevents browser tampering.
NetworkKeeps execution on the quoted network.
Destination addressPrevents delivery redirection.
Rate, spread, feeDefines partner-visible economics.
ExpiryBounds market risk.

Rate, spread, and fee

FieldMeaning
rateAll-in output per input for the side.
spreadBpsPool FX spread in basis points.
feeBpsPartner tier draw fee in basis points.
minOrderUsdtMinimum order in USDT-equivalent.
maxOrderUsdtMaximum order if configured.

All money and rate values are decimal strings. Use decimal libraries for ledger math.

Slippage framing

0Pools should be described as quote-locked or bounded, not as magical "no slippage" in every market condition. A firm quote reduces the partner's exposed slippage window because the user can only accept the returned terms before expiry. If the quote expires or liquidity is unavailable, request a new quote.

Good quote UX

  1. Validate pair, side, network, and amount before quote.
  2. Use indicative quotes for editing.
  3. Create a firm quote when the user reaches confirmation.
  4. Show output amount, rate, spreadBps, feeBps, network, destination, and expiry.
  5. Disable accept before expiry.
  6. Execute once with idempotency.
  7. Show pending until status is terminal.

Unavailable quotes

Unavailable quotes return no quoteId. Handle them as a product state:

{
  "available": false,
  "unavailableReason": "pool_dry"
}

Show a retry or alternate-pool option; do not retry in a tight loop.

Quote contract details

A quote is the product contract the user accepts. Treat it as immutable after creation.

Quote typeExecutable?Store?UI behavior
IndicativeNo.Optional analytics only.Refresh while user edits.
FirmYes until expiry.Required.Show countdown and final amount.
ExpiredNo.Required if shown/accepted.Disable accept and request fresh quote.
AcceptedNo new edits.Required with trade linkage.Show pending/processing.

Firm quote example

{
  "quote_id": "pq_live_01J4",
  "pool_id": "EUR-USDT",
  "quote_type": "firm",
  "side": "buy",
  "source_asset": "EUR",
  "source_amount": "100.00",
  "target_asset": "USDT",
  "target_amount": "107.42",
  "expires_at": "2026-06-28T20:14:30Z",
  "executable": true
}

Error treatment

Error shapeProduct behavior
Quote expired.Request fresh quote and require user confirmation again.
Amount outside limits.Show min/max before creating another quote.
Pool unavailable.Disable action and offer retry later.
Idempotency conflict.Render existing trade if same order; investigate if different order.

Implementation depth

This page is about designing quote UX around preview, lock, expiry, fees, and execution. For developers, the durable boundary is simple: your product should depend on indicative rate, firm quote id, expiry, spread bps, fee bps, and unavailable reasons; it should not depend on source pricing, market-maker terms, and hedging decisions. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.

Product scenario

A user types an amount and sees a refreshing estimate. When they tap confirm, the server locks a firm quote and the UI shows a countdown tied to expiresAt.

Before and after in practice

Before 0PoolsWith 0Pools
Users accept an estimate that was never executable, creating slippage complaints and refund pressure.Users accept a firm quote with a clear expiry, and stale quotes cannot be executed.
Product teams infer liquidity behavior from provider-specific screens or manual notes.Product teams branch on 0Pools objects: pool, quote, trade, balance, webhook, and ledger.
Support asks engineering to reconstruct state from logs.Support starts from request id, quote id, trade id, event id, and ledger id.

System flow

Records to keep

RecordWhy it mattersExample
quote_typeDistinguishes preview from executable terms.firm
rateAll-in rate shown to user.1.0731
expires_atCountdown source.2026-06-28T...
unavailable_reasonWhy no executable quote exists.pool_dry

A useful implementation stores these records before adding optional analytics. Analytics can be rebuilt from durable state; missing ids usually cannot be reconstructed after a customer-impacting failure.

Example product record

{
  "product_area": "quotes-pricing",
  "partner_reference": "partner_order_123",
  "pool_id": "EUR-USDT",
  "quote_id": "pq_test_123",
  "transact_id": "pt_test_456",
  "status": "reserved",
  "request_id": "req_01HZY0POOLS",
  "reconciliation_state": "open"
}

This record is intentionally partner-facing. It references 0Pools objects and your own product ids, but it does not include private liquidity routes, treasury balances, raw provider payloads, or customer secrets.

Failure modes and recovery

Failure modeProduct response
Indicative quote executedOnly firm quotes return executable quoteId.
Countdown hiddenShow expiry before the accept action.
Fee fields droppedPersist spread and fee fields for support.
Price refreshed after acceptExecute the accepted quote id only.

Use-case patterns

PatternHow 0Pools helps
Quote screenRefresh indicative price while editing.
Confirm screenLock firm terms.
Support ticketExplain displayed price from quote fields.

Developer checklist

  • Read runtime discovery and capabilities before rendering enabled actions.
  • Create firm quotes only when the user is ready to accept the terms.
  • Execute from your server with an idempotency key.
  • Treat webhooks and status reads as the source of truth for settlement state.
  • Reconcile by durable ids first, then by amount and timestamp.
  • Do not branch product behavior on provider names, route names, reserve balances, or treasury assumptions.

On this page