0Bit Documentation

Retrieve a 0Pools quote

GET /pools/quotes/{quoteId} - Read a quote and its derived status without consuming or extending it.

0Pools API pages are for approved headless partners. They cover the partner-visible quote, transact, status, trade, and balance lifecycle only.

Endpoint

FieldValue
MethodGET
Path/pools/quotes/{quoteId}
AreaQuotes
Operation idgetQuote
Auth boundarySecret key from your server.

Use it for

Retrieve a previously created firm quote and read its current derived status without consuming, extending, or re-pricing it.

Use this endpoint only for the partner-scoped resource it describes. Store your own reference id, the returned 0Bit object id, the request id, timestamps, and the current status so support and reconciliation do not depend on browser callbacks alone.

Firm quotes only

Only firm quotes are persisted and addressable by quoteId. Indicative quotes are price-only, are never assigned a quoteId, and are not retrievable here. A quoteId that is unknown to your partner scope returns 404.

Path parameters

ParameterInTypeDescription
quoteIdpathstringThe id returned by POST /pools/{id}/quote for a firm quote.

This call is a pure read

Retrieving a quote does not change it. It does not consume the quote, extend its expiry, re-price it, or move any money. Use it to confirm whether a stored quote is still actionable before you transact, or to reconcile a quote after the fact.

To execute a quote, call POST /pools/{id}/transact. To explicitly decline one, call POST /pools/quotes/{quoteId}/reject.

Derived status

The response carries a status that 0Pools derives from the quote's lifecycle at read time. A freshly created firm quote is active. It then resolves into exactly one terminal state.

StatusMeaningHow it is reached
activeStill locked and executable until expiresAt.Created and not yet transacted, rejected, or expired.
consumedAlready executed; a trade was created against this quote.POST /pools/{id}/transact succeeded for the quote.
expiredThe short time-to-live elapsed before any transact or reject.Read happens after expiresAt with no transact or reject.
rejectedExplicitly declined and permanently unusable. Distinct from consumed.POST /pools/quotes/{quoteId}/reject was called.

Status precedence

When more than one condition applies, the highest-precedence state wins: rejected > consumed > expired > active. A quote that was rejected reads as rejected even if its expiresAt has since passed, and a quote that was transacted reads as consumed even if it is now past expiry. Branch on status, not on the wall clock.

Response fields

Money and rate values are decimal strings. Basis-point fields are integers. fiatAmount and cryptoAmount are the two legs of the quote: for on_ramp the customer pays fiatAmount to receive cryptoAmount; for off_ramp the customer sells cryptoAmount to receive fiatAmount.

FieldTypeDescription
quoteIdstringStable id that joins quote, trade, status, and reconciliation records.
poolIdstringThe pool this quote was priced against, for example EUR-USDT.
pairstringThe pool pair, for example EUR/USDT.
sidestringon_ramp or off_ramp.
cryptoNetworkstringThe chain the trade transacts on, locked on the quote (tron, ethereum, bsc, polygon, or solana).
fiatAmountstringFiat leg of the quote (decimal string).
cryptoAmountstringCrypto leg of the quote (decimal string).
ratestringLocked rate as output-per-input (decimal string).
spreadBpsintegerSpread component, in basis points.
feeBpsintegerFee component, in basis points.
statusstringDerived status: active, consumed, expired, or rejected.
expiresAtstringRFC 3339 timestamp when the lock ends (firm quotes are short-lived, roughly 15 seconds).
consumedAtstring | nullRFC 3339 timestamp when the quote was transacted, or null if it was not consumed.
rejectedAtstring | nullRFC 3339 timestamp when the quote was rejected, or null if it was not rejected.
createdAtstringRFC 3339 timestamp when the quote was created.

The crypto network is locked on the quote

cryptoNetwork is fixed when the quote is created and selects the pool the trade transacts on. It is never re-read from the transact body. Branch on status to decide whether the quote is still actionable; there is no executable flag on this response.

Request

curl -X GET https://pools-api.0bit.app/v1/pools/quotes/quote_test_abc123 \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response examples

{
  "quoteId": "quote_test_abc123",
  "poolId": "EUR-USDT",
  "pair": "EUR/USDT",
  "side": "on_ramp",
  "cryptoNetwork": "tron",
  "fiatAmount": "100.00",
  "cryptoAmount": "93.09",
  "rate": "1.0742",
  "spreadBps": 45,
  "feeBps": 20,
  "status": "active",
  "expiresAt": "2026-06-28T14:32:15Z",
  "consumedAt": null,
  "rejectedAt": null,
  "createdAt": "2026-06-28T14:32:00Z"
}
{
  "quoteId": "quote_test_abc123",
  "poolId": "EUR-USDT",
  "pair": "EUR/USDT",
  "side": "on_ramp",
  "cryptoNetwork": "tron",
  "fiatAmount": "100.00",
  "cryptoAmount": "93.09",
  "rate": "1.0742",
  "spreadBps": 45,
  "feeBps": 20,
  "status": "consumed",
  "expiresAt": "2026-06-28T14:32:15Z",
  "consumedAt": "2026-06-28T14:32:08Z",
  "rejectedAt": null,
  "createdAt": "2026-06-28T14:32:00Z"
}
{
  "quoteId": "quote_test_abc123",
  "poolId": "EUR-USDT",
  "pair": "EUR/USDT",
  "side": "on_ramp",
  "cryptoNetwork": "tron",
  "fiatAmount": "100.00",
  "cryptoAmount": "93.09",
  "rate": "1.0742",
  "spreadBps": 45,
  "feeBps": 20,
  "status": "expired",
  "expiresAt": "2026-06-28T14:32:15Z",
  "consumedAt": null,
  "rejectedAt": null,
  "createdAt": "2026-06-28T14:32:00Z"
}
{
  "quoteId": "quote_test_abc123",
  "poolId": "EUR-USDT",
  "pair": "EUR/USDT",
  "side": "on_ramp",
  "cryptoNetwork": "tron",
  "fiatAmount": "100.00",
  "cryptoAmount": "93.09",
  "rate": "1.0742",
  "spreadBps": 45,
  "feeBps": 20,
  "status": "rejected",
  "expiresAt": "2026-06-28T14:32:15Z",
  "consumedAt": null,
  "rejectedAt": "2026-06-28T14:32:05Z",
  "createdAt": "2026-06-28T14:32:00Z"
}

Errors

Every error uses the unified envelope { type, code, message, request_id, doc_url, statusCode }, and every response carries an X-Request-Id header. Branch on type and code, not on the human-readable message.

StatustypeWhen
401unauthorizedMissing or invalid secret key.
403forbiddenWrong key mode (code is key_mode_mismatch). This is a secret-key-only route with no entitlement check, so the pool-access denial codes do not apply here.
404not_foundQuote id is unknown, is indicative (never persisted), or belongs to another partner.

Cross-tenant reads return 404, never 403

Quotes are partner-scoped. A quoteId that exists but belongs to a different partner is reported as 404 not_found, identical to a quote id that never existed. 0Pools never confirms the existence of another partner's resource and never returns 403 to signal ownership. Do not surface foreign or guessed quote ids to end users.

{
  "type": "not_found",
  "code": "not_found",
  "message": "Quote not found.",
  "request_id": "req_test_9f2c1a",
  "doc_url": null,
  "statusCode": 404
}

Production rules

  • Keep secret keys on your server.
  • Validate environment, mode, entitlement, asset, network, and amount before the call.
  • Branch on the machine-readable status, error code, object id, and request id; never derive expiry from the clock when status already tells you.
  • Treat any non-active status as final for that quote: request a fresh quote rather than retrying the same id.
  • Treat examples and placeholder ids as fake data only.

Public boundary

This reference covers partner-visible discovery, quote, transact, status, trade, and balance behavior. Liquidity operations, routing internals, provider details, reserve logic, and runbooks are outside the public API contract.

On this page