Pool availability
How 0Pools communicates entitlement, capability, runtime liquidity, quote expiry, and execution gates.
Availability in 0Pools has layers. A partner can be entitled to a pool, the pool can support a side and network, and a specific quote can still be unavailable because runtime liquidity or pricing cannot safely support it right now.
Availability stack
Layers
| Layer | Question | Developer handling |
|---|---|---|
| Account | Is the partner active and approved? | Show account/configuration state. |
| Entitlement | Can this partner see this pool? | Do not display absent pools. |
| Capability | Does this pool support the requested side/network/limit? | Validate before quote. |
| Runtime | Can this exact request be priced now? | Branch on available. |
| Quote | Is the firm quote still active? | Disable accept after expiry. |
| Execution | Did the accepted trade settle, fail, release, or return? | Update ledger from terminal state. |
Unavailable quote response
Unavailable quotes are not always errors. The API can return available: false with HTTP 200 and no quoteId.
| Reason | Meaning | Product response |
|---|---|---|
pool_dry | Not enough available depth for this request. | Offer retry later or a different pool. |
engine_unavailable | Pricing/reservation service cannot respond safely. | Show temporary unavailability. |
rate_unavailable | A current rate cannot be sourced. | Ask user to refresh later. |
User messaging
Use plain user-safe states:
- "This route is not available right now."
- "Quote expired. Refresh for a new price."
- "This account is not enabled for this flow."
- "Your transaction is pending settlement."
Avoid internal explanations such as venue outage, treasury refill, or route failure unless 0Bit support explicitly gives that wording.
Retry policy
| Case | Retry? |
|---|---|
| Indicative quote unavailable | Retry with backoff or offer another route. |
| Firm quote expired | Request a new quote. |
| Reservation conflict | Fetch quote/trade state, then request new quote if needed. |
| Rate limited | Do not loop; show limit/account state. |
| Access denied | Do not retry; fix account configuration. |
Availability decision tree
This tree is the product-safe way to think about availability. It avoids exposing private liquidity reasons while still giving the user a clear path.
Before and after
| Before 0Pools | With availability layers |
|---|---|
| "Supported" meant a static asset list. | Supported means entitled, capable, and available for this request. |
| Users discovered unsupported flows after submitting. | UI can hide or disable flows before firm quote. |
| Runtime liquidity problems looked like application errors. | available: false becomes a normal user state. |
| Expired prices were accepted accidentally. | Quote expiry blocks execution and forces refresh. |
Example product states
{
"pool_id": "EUR-USDT",
"account_enabled": true,
"entitled": true,
"capability_valid": true,
"runtime_available": false,
"unavailable_reason": "rate_unavailable",
"user_state": "retry_later"
}Do not treat runtime_available: false as a server crash. It can mean the product is working correctly by refusing to quote a request that should not be accepted right now.
Monitoring availability
Track availability at each layer:
- account/access failures
- entitlement misses
- capability validation failures
- runtime unavailable reasons
- quote expiry rate
- transact conflicts
- terminal failure/release/return rate
Separating these layers stops teams from blaming liquidity when the issue is actually account setup, UI validation, or stale quote handling.
Availability reason model
Availability needs a product-safe reason model. The partner should not guess from missing quotes.
| Reason category | User-safe copy | Developer action |
|---|---|---|
not_entitled | "This route is not enabled for your account." | Hide lane and contact support. |
capability_disabled | "This asset or network is not currently supported." | Refresh discovery and disable action. |
amount_out_of_bounds | "Enter an amount between the supported limits." | Validate before quote. |
temporarily_unavailable | "This pool cannot quote right now." | Retry later with backoff. |
quote_expired | "The quote expired. Request a new quote." | Create a fresh quote; do not reuse old terms. |
Availability decision flow
Monitoring rules
Track availability by pool, side, network, amount band, environment, and partner. A single global "0Pools available" metric is not useful enough for operations.
Implementation depth
This page is about modeling availability as layered state, not a permanent promise. For developers, the durable boundary is simple: your product should depend on entitlement, capability, runtime available flag, unavailable reason, and quote expiry; it should not depend on inventory depth, provider health, and route health calculations. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.
Product scenario
A partner opens the buy screen while a pool is temporarily unavailable. The UI can still show the lane as approved, but it disables quote acceptance and explains that pricing is temporarily unavailable.
Before and after in practice
| Before 0Pools | With 0Pools |
|---|---|
| Products equate supported assets with live availability and let users continue until an execution failure. | The product separates supported, entitled, available, quoted, reserved, and settled states. |
| 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
| Record | Why it matters | Example |
|---|---|---|
available | Runtime boolean for the pool. | false |
unavailable_reason | Machine reason for branching. | pool_dry |
checked_at | When the UI made the decision. | 2026-06-28T... |
retry_after | Partner policy for refreshing. | 30s |
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": "pool-availability",
"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 mode | Product response |
|---|---|
| Supported treated as available | Always check current availability before quote. |
| Unavailable shown as error | Render a normal temporary unavailable state. |
| Retry storm | Back off and refresh capabilities. |
| Quote expired | Ask for confirmation on a fresh firm quote. |
Use-case patterns
| Pattern | How 0Pools helps |
|---|---|
| Buy screen | Disable amount submit when unavailable. |
| Ops dashboard | Track quote success rate. |
| Status page | Show account-safe availability messages. |
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.