0Bit Documentation

Create a 0Gate session

POST /gate_sessions - Create a hosted session and return the browser-safe client secret once.

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.

A session binds an amount and currency server-side, then hands the browser a one-time client_secret. The browser presents that secret to the embed bootstrap to frame the widget against this exact, locked session. Create the session from your server with a secret key; the user never sees your sk_*.

Endpoint

FieldValue
MethodPOST
Path/v1/gate_sessions
AreaSessions
Operation idcreateSession
Auth boundarySecret key from your server.

The full request URL is https://gate-api.0bit.app/v1/gate_sessions.

Use it for

Create a hosted session and return the browser-safe client secret once.

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.

Production rules

  • Keep secret keys on your server. This endpoint requires a sk_* key. A pk_* publishable key is browser-only and used solely for the embed bootstrap.
  • Validate environment, mode, entitlement, asset, network, and amount before the call.
  • Send an Idempotency-Key for the logical write and retry timeouts with the same key.
  • Capture client_secret on this create response — it is returned once and never appears on retrieve or list.
  • Branch on machine-readable status, error code, object id, and request id.
  • Treat examples and placeholder ids as fake data only.

Request headers

HeaderRequiredUse it for
AuthorizationYesBearer sk_test_… or Bearer sk_live_…. The key's mode (test/live) is inherited by the session.
Idempotency-KeyYesA UUID for this logical create. Repeats with the same key and body collapse to the original response.
Content-TypeYesapplication/json.

Idempotency protects retries

Send a fresh Idempotency-Key UUID per create and reuse the same key when you retry a timed-out request. The server returns the original session instead of creating a duplicate.

Request body

FieldRequiredTypeUse it for
amountYesdecimal stringPositive amount, max 8 fractional digits. Bound to the session; later widget actions must match it exactly. Always a string, never a float.
currencyYesstring (ISO 4217)Three-letter fiat code, for example EUR. Uppercased server-side.
return_urlYesstring (https URI)Where the widget sends the user after a successful flow. HTTPS only (loopback allowed in dev); the URL's origin must be in your allowed_domains.
cancel_urlNostring (https URI)Where the widget sends the user on cancel. Same origin rules as return_url.
target_tokenNostringConstrain the session to a single token, for example USDC. Uppercased server-side.
target_networkNostringConstrain the session to a single network, for example ETHEREUM. Uppercased server-side.
flowNoon_ramp/off_ramp/swapLock the widget to one flow and hide the buy/sell/swap tab strip. Omit for the legacy "open" widget where the user picks.
wallet_addressNostring (≤128)Pre-fill the destination wallet. Validated against the resolved network at flow time, not at create.
user_referenceNostring (≤128)Opaque partner-side id (your user id, order id, CRM record). Echoed in webhook payloads for correlation.
metadataNoobjectOpaque per-session notes, returned verbatim. Not used for business logic.
quote_preview_idNostring (24-hex)Id from POST /v1/quotes/preview. When supplied, amount/currency/asset/side must match the locked preview or the request is rejected.
kyc_packageNo (kyc_trusted partners only)objectPartner-supplied pre-verified KYC. Contract-gated — only accepted when your partner record is kyc_trusted; otherwise 403 with code: kyc_package_not_trusted. The raw body is never echoed in any response.

Money values are strings

amount is a decimal string, never a float (for example "100.00"). The bound amount is enforced on every later action against the session.

return_url must be an allowed origin

The origin of return_url (and cancel_url, if set) must already be listed in your allowed_domains. An origin that is not allowed is rejected — see the errors table below.

Response

On success the server returns HTTP 201 Created with the GateSession object plus a one-time client_secret.

client_secret is shown once

client_secret (gsec_<id>_…) is returned only on this create call. Retrieve and list never return it. Persist it now, or rotate the session by creating a new one.

Response fields

FieldWhen presentUse it for
idAlwaysServer-assigned session id. Join session, transaction, and webhook records.
objectAlwaysgate_session discriminator.
partner_idAlwaysThe partner that owns the session.
modeAlwaystest or live, inherited from the sk_* that created it.
amountAlwaysThe bound amount, as a decimal string.
currencyAlwaysThe bound, uppercased ISO 4217 code.
return_urlAlwaysThe success redirect you supplied.
cancel_urlAlwaysThe cancel redirect, or null.
statusAlwaysLifecycle state. A fresh session is open.
expires_atAlwaysISO-8601 expiry, default 24h after creation.
created_atAlwaysISO-8601 creation time, or null.
flowAlwaysThe locked flow, or null for the open widget.
target_tokenAlwaysThe token constraint, or null.
target_networkAlwaysThe network constraint, or null.
wallet_addressAlwaysThe pre-filled wallet, or null.
user_referenceAlwaysYour opaque correlation id, or null.
kyc_pre_verifiedAlwaystrue only when a kyc_trusted partner supplied an accepted kyc_package.
metadataAlwaysYour opaque notes, returned verbatim.
client_secretCreate onlygsec_<id>_…. Hand to the browser for the embed bootstrap. Never returned again.

Examples

curl -X POST https://gate-api.0bit.app/v1/gate_sessions \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "100.00",
    "currency": "EUR",
    "return_url": "https://partner.example/checkout/done"
  }'
{
  "id": "67a1f3b9e4b0c10001234567",
  "object": "gate_session",
  "partner_id": "507f1f77bcf86cd799439011",
  "mode": "test",
  "amount": "100.00",
  "currency": "EUR",
  "return_url": "https://partner.example/checkout/done",
  "cancel_url": null,
  "status": "open",
  "expires_at": "2026-05-27T12:00:00.000Z",
  "created_at": "2026-05-26T12:00:00.000Z",
  "flow": null,
  "target_token": null,
  "target_network": null,
  "wallet_address": null,
  "user_reference": null,
  "kyc_pre_verified": false,
  "metadata": {},
  "client_secret": "gsec_67a1f3b9e4b0c10001234567_AbCdEfGhIjKlMnOpQrStUvWxYz012345"
}

Store client_secret now — it is never returned again. Hand it to the browser to bootstrap the embedded widget.

{
  "id": "67a1f3b9e4b0c10001234999",
  "object": "gate_session",
  "partner_id": "507f1f77bcf86cd799439011",
  "mode": "test",
  "amount": "250.00",
  "currency": "EUR",
  "return_url": "https://partner.example/checkout/done",
  "cancel_url": null,
  "status": "open",
  "expires_at": "2026-05-27T12:00:00.000Z",
  "created_at": "2026-05-26T12:00:00.000Z",
  "flow": "on_ramp",
  "target_token": "USDC",
  "target_network": "ETHEREUM",
  "wallet_address": null,
  "user_reference": "order_abc123",
  "kyc_pre_verified": false,
  "metadata": {},
  "client_secret": "gsec_67a1f3b9e4b0c10001234999_ZyXwVuTsRqPoNmLkJiHgFeDcBa987654"
}

A flow lock forces the widget into one flow and hides the tab strip; target_token/target_network constrain what the user can pick.

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": "forbidden",
  "code": "kyc_package_not_trusted",
  "message": "Example forbidden error using fake data.",
  "request_id": "req_test_000000000123",
  "doc_url": null,
  "statusCode": 403
}
StatustypeWhen it happens
400invalid_requestBad body — malformed amount, an unknown currency, a non-HTTPS return_url, a return_url/cancel_url whose origin is not in allowed_domains, or a quote_preview_id that is missing, expired, already used, or mismatched.
401unauthorizedMissing or invalid secret key.
403forbiddenAccess denied. Branch on code: kyc_package_not_trusted (partner is not kyc_trusted), quota_exhausted (live keys only — session cap reached for the period; test mode is unmetered), or kit_blocks_not_enabled (a flow was sent but flow sessions are not enabled).
429rate_limitedThrottled at 10 creates per minute per key. Back off and retry with the same Idempotency-Key.
5xxserver_errorTransient server or upstream failure. Retry with bounded backoff and the same Idempotency-Key.

Public boundary

This reference covers partner-scoped endpoint behavior, authentication, idempotency, webhook verification, and support-safe records. Internal operations, settlement venues, fiat-rail providers, KYC vendors, administrative routes, and unsupported availability claims are outside the public API contract.

On this page