Skip to main content
Webhooks notify your application after deposits, withdrawals, and exchange orders change. REST remains the source of truth, so use the identifiers in a webhook to retrieve current state whenever your workflow needs confirmation.

Event type guides

Every delivery uses the same five-field top-level envelope. The linked event guides contain complete, schema-valid JSON bodies for each data shape. The body does not contain endpoint, delivery-attempt, signing-secret, or account routing metadata.

Subscribe to events

Create an HTTPS endpoint with POST /v1/partner/webhooks. An account can have at most three enabled endpoints. Subscriptions are exact event names; wildcard subscriptions are not supported.
  • deposit.action_required
  • deposit.success
  • deposit.failed
  • withdrawal.success
  • withdrawal.failed
  • exchange.accepted
  • exchange.filled
  • exchange.replaced
  • exchange.cancelled
  • exchange.rejected
Create the endpoint from your server and store the returned secret immediately:
Your API key must have wallets:view for deposit and withdrawal topics, and trades:view for exchange topics, in addition to the webhook-management scope required to create or update an endpoint. The create response contains a generated whsec_... signing secret exactly once. Store it in your secrets manager. Rotating a secret also returns the new value exactly once. During the 24-hour rotation overlap, the signature header contains signatures for both the new and previous secret; accept the delivery when any one signature verifies with a secret you currently trust.

Manage an endpoint

Use the endpoint ID returned at creation:
PUT replaces the complete endpoint configuration, including the subscription list. To stop deliveries without deleting history, update the endpoint with enabled: false. Use DELETE /partner/webhooks/{webhook_id} only when the endpoint is no longer needed. There is no synthetic test-delivery endpoint. Validate your receiver in staging by completing a staging workflow that produces one of its subscribed events, then confirm the event and delivery through the history endpoints. Endpoint creation by itself does not test network delivery.

Delivery contract

Stabyl sends the exact JSON body with these headers:
Calculate the signature over the unmodified request bytes:
Use HMAC-SHA256 with the 32 bytes obtained by removing whsec_ and decoding the remaining standard Base64 text. Compare signatures in constant time and reject timestamps outside your chosen tolerance. The examples below use five minutes.
Read the raw body before any JSON middleware changes whitespace, key order, or encoding. Parse JSON only after signature verification succeeds.

Node.js verification

Python verification

Retries, duplicates, and ordering

A failed initial delivery can receive up to three retries. The nominal retry delays are approximately 30 seconds, 5 minutes, and 30 minutes, with jitter. Stabyl retries transient network failures and HTTP 408, 409, 425, 429, and 5xx responses. Other 4xx responses and redirects are not retried. A valid Retry-After response can delay a retry by up to 30 minutes. Network ambiguity can repeat the same logical attempt, so always deduplicate by webhook-id. No ordering is guaranteed across events, endpoints, topics, or retries. Return any 2xx response only after your durable inbox transaction is committed. Use GET /v1/partner/webhook/events and GET /v1/partner/webhook/deliveries for eventually consistent delivery history. History may lag live delivery and does not replace REST reconciliation.