Monitor pool health
What 0Pools partners should monitor: availability, quote success, reserved trades, terminal states, webhooks, and reconciliation.
Production 0Pools integrations need monitoring around product-visible signals. You do not need private treasury dashboards to operate your integration; you need to know whether users can quote, execute, settle, and reconcile.
Monitoring map
Metrics to track
| Metric | Why |
|---|---|
| Pool discovery errors | Detect account/key/environment issues. |
| Quote availability rate | Detect dry pools or pricing outages. |
| Firm quote expiry rate | Detect UX delays or stale acceptance. |
| Transact conflict rate | Detect duplicate/expired quote problems. |
| Reserved trade age | Detect stuck settlement. |
| Terminal state mix | Detect failures/releases/returns. |
| Webhook delivery failures | Detect event-processing gaps. |
| Ledger mismatch count | Detect finance/reconciliation issues. |
Alerts
Alert on:
- repeated
engine_unavailable - repeated
rate_unavailable - spike in
pool_dry - reserved trades older than your approved threshold
- webhook failures
- returned trades
- ledger entries without matching internal order
Dashboard fields
Your internal dashboard should show pool id, quote id, trade id, side, pair, amount, network, status, created time, settled time, request id, and user/order reference.
Do not require support agents to know private route names.
Example health dashboard
The dashboard should answer four questions quickly:
- Can users get a quote?
- Can accepted quotes turn into trades?
- Are trades reaching terminal states?
- Can finance reconcile the product ledger?
If the dashboard cannot answer those questions without internal operator access, the partner integration is not observable enough.
Example alert policy
| Alert | Signal | Suggested product response |
|---|---|---|
| Quote outage | Quote availability drops below your internal threshold. | Hide the affected pool or show a temporary unavailable state. |
| Expiry spike | Many firm quotes expire before acceptance. | Shorten user decision path, reduce confirmation steps, or refresh earlier. |
| Duplicate execution | Idempotency conflicts increase. | Audit retry logic and prevent double-click submit paths. |
| Settlement lag | Reserved trades age beyond approved support window. | Keep funds pending and escalate with quote/trade ids. |
| Webhook gap | Delivery failures increase or event age grows. | Poll trusted reads until delivery recovers. |
| Reconciliation gap | Ledger rows fail to match partner orders. | Freeze finance close for those rows and attach request ids. |
Incident timeline example
{
"incident": "quote_availability_drop",
"pool_id": "EUR-USDT",
"started_at": "2026-06-28T12:04:00Z",
"quote_availability_5m": "72.4%",
"top_reason": "rate_unavailable",
"partner_action": "show_retry_state",
"support_reference": "req_9fb1"
}The incident object deliberately avoids provider names and reserve details. It gives product, support, and finance enough context to act while 0Bit operations investigate the private liquidity layer.
Monitoring specification
Pool health monitoring should be segmented enough to explain incidents.
| Metric | Dimension | Alert example |
|---|---|---|
| Discovery success rate | partner, environment. | No entitled pools returned for active partner. |
| Quote success rate | pool, side, network, amount band. | Quote failures above threshold for 10 minutes. |
| Quote expiry acceptance | product, client version. | Users attempting expired quotes. |
| Reserved age | pool, trade status. | Reserved trades older than expected window. |
| Webhook delivery failure | endpoint, event type. | Consecutive non-2xx responses. |
| Ledger mismatch | close date, asset. | Settled trade missing ledger row. |
Alert payload
{
"alert": "reserved_age_high",
"pool_id": "EUR-USDT",
"environment": "live",
"oldest_reserved_trade_id": "pt_live_9A2",
"oldest_age_seconds": 900,
"sample_request_ids": ["req_01J4A", "req_01J4B"]
}Dashboard minimum
Show availability, quote success, firm quote expiry rate, transact success, reserved-age distribution, terminal-state split, webhook health, ledger exceptions, and current partner-visible balance.
Implementation depth
This page is about monitoring partner-visible health signals without exposing private inventory. For developers, the durable boundary is simple: your product should depend on availability, quote success, expired quotes, reserved age, terminal status, webhook delivery, and reconciliation gaps; it should not depend on venue balances, worker internals, and treasury refill alerts. That boundary is what lets 0Pools improve liquidity operations without forcing every partner to rebuild product code.
Product scenario
A partner dashboard tracks whether users can quote, execute, receive terminal states, and reconcile ledger entries. It does not need private pool balances to detect a broken user flow.
Before and after in practice
| Before 0Pools | With 0Pools |
|---|---|
| Teams notice problems only when users complain or daily finance close fails. | The product watches leading indicators and opens an incident before state drift becomes finance drift. |
| 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 |
|---|---|---|
quote_success_rate | Share of quote attempts returning available terms. | 98.7% |
reserved_age_p95 | How long reserved trades remain pending. | 42s |
webhook_lag | Delay from event to processing. | 4s |
recon_gap_count | Unmatched records at close. | 0 |
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": "monitor-pool-health",
"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 |
|---|---|
| Only uptime monitored | Track lifecycle outcomes, not just 200s. |
| No reserved-age alert | Alert when pending trades age beyond policy. |
| Webhook lag hidden | Measure delivery and handler time. |
| Reconciliation ignored | Close the loop daily. |
Use-case patterns
| Pattern | How 0Pools helps |
|---|---|
| Partner ops dashboard | Track user-impacting health. |
| Incident response | Identify quote vs execution vs webhook issues. |
| Finance close | Catch unmatched records early. |
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.