0Bit Documentation

How 0Pools works

How 0Pools turns a partner liquidity request into an entitled quote, idempotent trade, status record, and reconciliation trail.

0Pools works like a headless checkout for liquidity. The partner backend prepares the order, 0Pools prices and locks terms, the partner accepts once, and both sides reconcile from a trade lifecycle.

Workflow overview

Step 1: entitlement

Entitlement is the first filter. If the partner is not active, verified, tiered, and allowed for a pool, execution never starts.

This is why 0Pools can be headless without being public. The API contract is server-side, but the account review decides whether that server is allowed to draw liquidity.

Step 2: availability

Availability is checked twice:

CheckWhat it answers
Discovery availabilityIs this pool generally usable by this partner right now?
Quote availabilityCan this exact side, pair, network, amount, and market condition be quoted now?

An unavailable quote is a valid response. It avoids issuing stale locks when the pool cannot safely execute.

Step 3: quote lock

The firm quote is the contract the user accepts.

{
  "available": true,
  "type": "firm",
  "executable": true,
  "quoteId": "pq_test_123",
  "rate": "1.0731",
  "spreadBps": 25,
  "feeBps": 30,
  "expiresAt": "2026-01-01T00:00:15Z"
}

This is the piece that reduces exposed slippage for the partner UX: the user is accepting a bounded quote with an expiry, not an open-ended promise. After expiry, get a new quote.

Step 4: execution

transact consumes a firm quote and creates a trade. It is idempotent so duplicate user clicks or retrying a timeout do not create duplicate trades.

Step 5: status

The trade status is the durable business signal.

StatusProduct handling
reservedPending. Do not final-credit the user.
settledSuccess. Finalize ledger.
failedFailure. Trigger product refund/support flow.
releasedClean unwind. Let user retry.
returnedPost-settlement return. Reconcile and alert support.

Step 6: reconciliation

Every production record should join:

  • Partner order id.
  • Pool id.
  • Quote id.
  • Transact id.
  • Request id.
  • Webhook event id.
  • Balance ledger ref.
  • Status timestamps.

That join is the infrastructure value: support and finance can reason about a money movement without guessing which internal system caused it.

Full lifecycle contract

The complete 0Pools lifecycle has three clocks: the quote clock, the execution clock, and the settlement clock. Production code should keep them separate.

ClockStarts whenEnds whenDeveloper responsibility
Quote clockA firm quote is created.expiresAt is reached or the quote is accepted.Disable accept after expiry and never silently change accepted terms.
Execution clockThe server calls transact.A trade id is returned or an idempotent prior result is returned.Use one idempotency key per accept attempt.
Settlement clockTrade is reserved.Status reaches settled, failed, released, or returned.Update user and ledger state only from trusted status/webhook data.

End-to-end trace example

{
  "order_id": "order_7841",
  "pool_id": "EUR-USDT",
  "quote_id": "pq_live_01J4",
  "quote_expires_at": "2026-06-28T20:14:30Z",
  "idempotency_key": "order_7841:accept:1",
  "transact_id": "pt_live_9A2",
  "status_history": [
    { "status": "reserved", "at": "2026-06-28T20:13:11Z" },
    { "status": "settled", "at": "2026-06-28T20:15:03Z" }
  ],
  "ledger_entry_id": "ledger_0pools_772"
}

Retry behavior

SituationCorrect behavior
Network timeout after transact request.Retry with the same idempotency key, then render the returned trade.
User clicks accept twice.Backend reuses or rejects based on the same order accept version.
Webhook arrives before the UI refreshes.Backend updates the ledger; UI reads server state.
Status remains reserved longer than expected.Keep pending state, alert operations, and do not credit as settled.

Implementation depth

This page is about following the request from entitlement to reconciliation. For developers, the durable boundary is simple: your product should depend on the lifecycle a partner can depend on in product code; it should not depend on the internal liquidity decision that fulfills the lifecycle. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.

Product scenario

A partner receives a user request, checks whether the requested lane is entitled, previews availability, locks terms, executes once, and waits for terminal status before posting final balance changes.

Before and after in practice

Before 0PoolsWith 0Pools
The app asks several liquidity providers for prices and tries to normalize incompatible statuses after the fact.The app talks to one 0Pools lifecycle and records one set of ids, statuses, and amounts.
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
entitlement_snapshotExplains why the lane was shown.active EUR-USDT
quote_termsThe accepted amount, rate, fees, and expiry.100.00 EUR
execution_ackThe reserved trade response.pt_test_456
terminal_eventThe final state used by the ledger.settled

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": "how-0pools-works",
  "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
Access deniedStop the flow and refresh account capabilities.
Available falseShow a clear unavailable state without promising delivery.
Quote consumedRetrieve existing trade or create a new quote.
Webhook missingPoll by quote id and reconcile from the API.

Use-case patterns

PatternHow 0Pools helps
First backend integrationImplement the lifecycle in order.
Product state machineMap API states to user screens.
Runbook creationDefine what support checks at each step.

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