liquidity_pool.* events are deprecated. During the rename window
(see ADR-030) Superbank emits both account.* and the legacy
liquidity_pool.* events for the same state change, so existing
handlers keep working. Subscribe to account.* going forward — the
liquidity_pool.* aliases will be removed in the next major release.
If you handle both, dedupe on data.id.
Every delivery uses the same JSON envelope. Field names are snake_case; the data object varies by event type. The full payload for each event is in Event payload reference at the bottom.
Compute sha256=HMAC-SHA256(secret, request_body) over the raw request body and compare it to the X-Superbank-Signature header using a constant-time comparison. Verify before parsing — see Common pitfalls.
Verify before parse. Run signature verification on the raw bytes
beforeJSON.parse. Frameworks that auto-parse JSON (Express
default, NestJS body parser) will silently re-serialize the body and
your HMAC will never match — use express.raw / request.data /
equivalent to hold onto the original bytes.
Return 200 fast, process async. Heavy work on the request thread
blows past the 30-second timeout and triggers retries. Acknowledge,
then enqueue.
Expect at-least-once delivery. Retries are real — the same event
can land twice. Make handlers idempotent on the event id (or on
data.id + status transition).
Don’t filter by source IP. Egress IPs change without notice;
rely on the signature.
Test deliveries land at your endpoint with two markers your handler should expect:
data.test: true — every test payload sets a top-level test: true inside data. Branch on it if you want to short-circuit business logic for test events.
Sentinel resource IDs — IDs use the prefix 00000000-0000-0000-0000-..., with the last digit identifying the resource type (...001 settlement request, ...002 outbound payment, etc.). Allow-list these prefixes if your handler validates IDs against your database.
Headers and signature are computed exactly as in production, so a handler that verifies signatures accepts test deliveries without any code branch.
webhook.site gives you an instant public URL to inspect deliveries without writing any handler code — useful for eyeballing payloads before you write parsing logic.
# Register the unique URL it generatescurl --request POST \ --url https://api-sandbox.superbank.co/v0/webhooks \ --header 'Content-Type: application/json' \ --header 'X-Api-Key: YOUR_API_KEY' \ --data '{ "url": "https://webhook.site/YOUR_UNIQUE_ID" }'
Save the secret from the response, then trigger a sandbox event (e.g., POST /v0/settlement-requests) and watch the delivery land in the webhook.site browser tab.
The data object differs per event. Expand the relevant section for a worked example. All examples carry production-shape fields; sandbox and production payloads have identical shape.
During the rename window each account.* event is also emitted under
its liquidity_pool.* alias with an identical data payload (the
event field is the only difference). Existing handlers will keep
receiving these until the next major release. Subscribe to the
canonical account.* events going forward.
Looking for the end-to-end on-ramping flow? See Real-Time
On-Ramping — the section
Detecting Completion shows where webhook events fit into the
settlement lifecycle.