0Bit Documentation

List webhook deliveries

GET /webhooks/deliveries - List partner-scoped webhook delivery records for diagnostics.

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.

This is the hub for webhook observability. It also carries the full event catalogue, the signature recipe, and the delivery and retry semantics that the replay and test endpoints refer back to.

Endpoint

FieldValue
MethodGET
Path/v1/webhooks/deliveries
AreaWebhooks
Operation idlistPartnerWebhookDeliveries
Auth boundarySecret key from your server.

Use it for

Read your own outbound webhook delivery log, most-recent first: which events delivered, which are still retrying, and which dead-lettered and why. The log is scoped to your partner — you never see another partner's deliveries.

Use it to diagnose a missed event, to confirm an endpoint outage has cleared, and to find the delivery id you then pass to replay. The payload_raw body is never returned here — the log is about delivery health, not payload inspection.

Server-side, secret key only

This endpoint requires an sk_* secret key sent from your server. pk_* publishable keys are browser-safe and only bootstrap the embed; they cannot read the delivery log.

Request

Query parameters

FieldRequiredTypeUse it for
statusNoenumFilter to one delivery state: pending, in_flight, succeeded, or dead_lettered.
limitNointegerPage size, 1200 (default 50).
skipNointegerNumber of records to skip for pagination, ≥ 0 (default 0).

Response

A list envelope whose data is an array of WebhookDelivery records, most-recent first.

FieldTypeUse it for
objectstringAlways list.
dataarrayArray of WebhookDelivery records (see below).
has_morebooleantrue when more records exist past this page; advance skip.
urlstringThe path this list was read from.

The WebhookDelivery record

FieldTypeUse it for
objectstringAlways webhook_delivery.
idstringDelivery id. Pass to replay.
event_idstringStable event id, also sent as the X-0bit-Event-Id header. Your cross-system dedupe key.
event_typestringThe event that was delivered, e.g. gate_session.completed. See the event catalogue below.
target_urlstringThe webhook_url the attempt was POSTed to.
statusenumpending, in_flight, succeeded, or dead_lettered.
attemptsintegerNumber of delivery attempts so far (max 5 before dead-letter).
last_response_statusinteger | nullHTTP status your endpoint last returned, or null if none yet.
last_errorstring | nullShort reason the last attempt failed, or null on success.
next_attempt_atstring | nullWhen the worker will retry next (ISO 8601), or null when terminal.
delivered_atstring | nullWhen a 2xx was received, or null if not yet delivered.
created_atstring | nullWhen the delivery record was created (ISO 8601).
updated_atstring | nullWhen the record last changed (ISO 8601).

Event catalogue

Every delivery carries one event_type. These are the partner-observable events:

event_typeFired when…Payload data
gate_session.createdA session is created.The full session object.
gate_session.processingA buy or sell linked to the session moves into processing.The full session object.
gate_session.completedA buy or sell linked to the session succeeds.The session plus a tx_refid to join to your order record.
gate_session.failedA buy or sell linked to the session fails.The full session object.
gate_session.expiredA session is first read past its expires_at.The full session object.
gate_session.cancelledA session is cancelled.The full session object.
gate_session.kyc_package_acceptedA KYC-trusted partner's submitted KYC package is accepted (audit trail).A redacted acceptance record — correlation ids and a timestamp, never raw KYC PII.
kyc.requiredA session is blocked pending KYC; the user completes it in the hosted flow.gate_session_id, kyc_status, and your user_reference.
customer.createdA customer record is created under your partner account.The customer object.
customer.updatedA customer record's details change.The customer object.
customer.deletedA customer record is deleted.The customer object (or its id reference).
partner.quota.warningYour account is approaching a usage quota.Quota usage counters (operational notification).
partner.quota.exhaustedA usage quota is exhausted and requests are being throttled or refused.Quota usage counters (operational notification).

Dedupe on the event id

Delivery is at-least-once, so the same event can arrive more than once. Use the event id (the envelope id, mirrored in the X-0bit-Event-Id header) as your idempotency key and ignore a repeat you have already processed.

Signature and headers

Every webhook POST to your webhook_url carries a signature plus three companion headers:

HeaderValue
Gate-Signaturet=<unix-ts>,v1=<hex> — the timestamped HMAC (see recipe below).
X-0bit-Timestamp<unix-ts> — the same value as t= in Gate-Signature.
X-0bit-Event-Id<uuid> — the event id; your dedupe key.
X-0bit-Event-TypeThe event_type, e.g. gate_session.completed.

Verify the signature

The v1 value is an HMAC-SHA256 (hex) computed over the string formed by the timestamp, a literal ., then the raw request body — sign the bytes you received, before any JSON re-serialization. Reject anything older than the 300-second skew tolerance, and compare with a constant-time equality check.

const crypto = require('crypto');

function verify(rawBody, header, secret, skewSeconds = 300) {
  const parts = Object.fromEntries(
    header.split(',').map((p) => p.split('=')),
  );
  const t = parseInt(parts.t, 10);
  if (Math.abs(Date.now() / 1000 - t) > skewSeconds) return false;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(parts.v1, 'hex'),
  );
}

Delivery and retry

  • At-least-once. Acknowledge with any 2xx; dedupe on the event id.
  • 10-second timeout per attempt. A 408 or 429 from your endpoint is treated as transient and retried.
  • Retry schedule: 1m, 5m, 30m, 2h. After 5 attempts with no 2xx, the delivery is dead-lettered.
  • A dead-lettered delivery surfaces here with status: dead_lettered and a last_error. Fix your handler, then replay it.

Examples

curl -G https://gate-api.0bit.app/v1/webhooks/deliveries \
  -H "Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  --data-urlencode "status=dead_lettered" \
  --data-urlencode "limit=20"
{
  "object": "list",
  "data": [
    {
      "object": "webhook_delivery",
      "id": "whd_test_67a1f3b9e4b0c10001234567",
      "event_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "event_type": "gate_session.completed",
      "target_url": "https://partner.example/webhooks/0bit",
      "status": "succeeded",
      "attempts": 1,
      "last_response_status": 200,
      "last_error": null,
      "next_attempt_at": null,
      "delivered_at": "2026-01-01T00:00:02Z",
      "created_at": "2026-01-01T00:00:01Z",
      "updated_at": "2026-01-01T00:00:02Z"
    }
  ],
  "has_more": false,
  "url": "/v1/webhooks/deliveries"
}
{
  "object": "webhook_delivery",
  "id": "whd_test_67a1f3b9e4b0c10009999999",
  "event_id": "9b2d6c1a-1111-2222-3333-444455556666",
  "event_type": "gate_session.completed",
  "target_url": "https://partner.example/webhooks/0bit",
  "status": "dead_lettered",
  "attempts": 5,
  "last_response_status": 500,
  "last_error": "HTTP 500: (empty body)",
  "next_attempt_at": null,
  "delivered_at": null,
  "created_at": "2026-01-01T00:00:01Z",
  "updated_at": "2026-01-01T02:36:01Z"
}

Fix your handler, then replay this delivery by id.

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": "unauthorized",
  "code": "unauthorized",
  "message": "Example error using fake data.",
  "request_id": "req_test_000000000123",
  "doc_url": null,
  "statusCode": 401
}
StatustypeWhen it happens
400invalid_requestBad query parameter — limit out of range, negative skip, or an unknown status.
401unauthorizedMissing or invalid secret key.
429rate_limitedThrottled. This route allows up to 60 requests per minute. Back off and retry.
5xxserver_errorTransient server failure. Retry with bounded backoff.

Production rules

  • Keep secret keys on your server. This endpoint requires an sk_* key.
  • Page with limit (≤ 200) and skip; do not assume unbounded list reads.
  • Dedupe on the event id; treat delivery as at-least-once.
  • Verify Gate-Signature over the raw body, enforce the 300-second skew, and compare in constant time.
  • Branch on machine-readable status, error code, object id, and request id.
  • Treat examples and placeholder ids as fake data only.

Public boundary

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

On this page