Retrieve a signed quote
GET /quotes/{id} - Retrieve the current state of a partner-scoped signed quote.
0Gate is the primary public integration path for hosted payment, ramp, and swap experiences. Keep secret-key operations on your server and hand only browser-safe values to the widget.
Endpoint
| Field | Value |
|---|---|
| Method | GET |
| Path | /v1/quotes/{id} |
| Area | Rails |
| Operation id | retrieveSignedQuote |
| Auth boundary | Secret key from your server. |
Use it for
Read a locked quote and its current redemption state by id. Use it to re-check a quote before redeeming, to confirm a quote was consumed after a rail call, or to detect that a lock has lapsed. An elapsed quote reports status: expired rather than 404.
The {id} path parameter is the id returned by POST /quotes. A quote that belongs to a different partner is 404 (cross-tenant access is never 403).
Use this endpoint only for the partner-scoped resource it describes. Store your own reference id, the returned quote id, the request id, timestamps, and the current status so support and reconciliation do not depend on browser callbacks alone.
Production rules
- Keep secret keys on your server. This endpoint requires a
sk_*key. - Validate environment, mode, and entitlement before the call.
- Branch on machine-readable status, error code, object id, and request id — read
statusto know whether a quote is still redeemable. - Treat examples and placeholder ids as fake data only.
Request
| Parameter | In | Required | Type | Use it for |
|---|---|---|---|---|
id | path | Yes | string | The locked-quote id returned by POST /v1/quotes, for example qt_test_9f8e7d6c5b4a. |
This is a read — there is no request body.
Response
200 returns the same signed LockedQuote (object: signed_quote) as the lock call, reflecting its current status.
| Field | Type | Use it for |
|---|---|---|
object | string | Always signed_quote. |
id | string | The locked-quote id. |
status | active/consumed/expired | Current redemption state. active is still redeemable; consumed was redeemed; expired lapsed. |
side | on_ramp/off_ramp | Locked direction. |
currency | string | Locked fiat code. |
asset | string | Locked crypto asset. |
payment_method | string | Locked method. |
fiat_amount | decimal string | Fiat leg of the locked conversion. |
crypto_amount | decimal string | Crypto leg of the locked conversion. |
exchange_rate | decimal string | Locked all-in rate for the chosen side. |
fees | object | Fee breakdown: spread, fixed, total (all decimal strings). |
fiat_pay_or_receive | decimal string | The fiat the user pays (on_ramp) or receives (off_ramp). |
usd_amount | decimal string | USD-normalised value of the conversion. |
signature | string | HMAC-SHA256 over the canonical quote payload, format t=<unix_seconds>,v1=<hex>. |
expires_at | string (date-time) | When the lock lapses. |
created_at | string (date-time) | When the quote was locked. |
Expiry is a status, not a 404
An elapsed quote still resolves — it returns 200 with status: expired. Branch on status, not on the HTTP code, to decide whether you can still redeem it.
Examples
curl https://gate-api.0bit.app/v1/quotes/qt_test_9f8e7d6c5b4a \
-H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"{
"object": "signed_quote",
"id": "qt_test_9f8e7d6c5b4a",
"status": "active",
"side": "on_ramp",
"currency": "EUR",
"asset": "USDC",
"payment_method": "sepa_credit_transfer",
"fiat_amount": "1000.00",
"crypto_amount": "1067.40",
"exchange_rate": "1.0674",
"fees": {
"spread": "5.30",
"fixed": "0.50",
"total": "5.80"
},
"fiat_pay_or_receive": "1000.00",
"usd_amount": "1073.10",
"signature": "t=1767225600,v1=4a7f...e9b2",
"expires_at": "2026-01-01T00:00:30Z",
"created_at": "2026-01-01T00:00:00Z"
}Still redeemable. Pass id as quote_id to a pay-in or pay-out before expires_at.
{
"object": "signed_quote",
"id": "qt_test_9f8e7d6c5b4a",
"status": "consumed",
"side": "on_ramp",
"currency": "EUR",
"asset": "USDC",
"payment_method": "sepa_credit_transfer",
"fiat_amount": "1000.00",
"crypto_amount": "1067.40",
"exchange_rate": "1.0674",
"fees": {
"spread": "5.30",
"fixed": "0.50",
"total": "5.80"
},
"fiat_pay_or_receive": "1000.00",
"usd_amount": "1073.10",
"signature": "t=1767225600,v1=4a7f...e9b2",
"expires_at": "2026-01-01T00:00:30Z",
"created_at": "2026-01-01T00:00:00Z"
}Already redeemed once. Lock a new quote before attempting another rail call.
Errors
All errors use the unified envelope and carry an X-Request-Id response header. Branch on code/type/statusCode, not on the free-form message.
{
"type": "not_found",
"code": "not_found",
"message": "Example not-found error using fake data.",
"request_id": "req_test_000000000123",
"doc_url": null,
"statusCode": 404
}| Status | type | When it happens |
|---|---|---|
401 | unauthorized | Missing or invalid secret key. |
403 | forbidden | Credential rejected or mode mismatch. |
404 | not_found | Quote id does not exist or is not scoped to this partner. Cross-tenant access is 404, never 403. |
429 | rate_limited | Request throttled. Back off and retry. |
5xx | server_error | Transient server or upstream failure. Retry with bounded backoff. |
Public boundary
This reference covers partner-scoped endpoint behavior, authentication, idempotency, webhook verification, and support-safe records. Internal operations, settlement venues, provider details, administrative routes, and unsupported availability claims are outside the public API contract.