Quick start
The shortest path from zero to a verified delivery:- Create an endpoint.
POST /v0/webhookswith a public URL — save thesecretfrom the response, you’ll need it to verify signatures. - Verify the signature on incoming requests with
HMAC-SHA256(secret, raw_body)against theX-Superbank-Signatureheader (jump to Verifying signatures). - Return
200quickly, then process asynchronously. Anything 2xx counts; anything else triggers a retry.
The basics
Supported events
| Event | When it fires |
|---|---|
account.created | A new account was provisioned |
account.updated | Account balance or status changed |
account.deleted | An account was deactivated |
payment.created | A new payment was created |
payment.updated | A payment status changed |
settlement_request.created | A new settlement request was created |
settlement_request.updated | A settlement request status changed |
Envelope and headers
Every delivery uses the same JSON envelope. Field names are snake_case; thedata object varies by event type. The full payload for each event is in Event payload reference at the bottom.
| Header | Description |
|---|---|
Content-Type | application/json |
X-Superbank-Signature | HMAC-SHA256 signature: sha256=<hex> |
X-Superbank-Event | Event type (e.g., payment.updated) |
Verifying signatures
Computesha256=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.
- Node.js
- Python
Reliability
Retry policy
If your endpoint returns a non-2xx response or times out (30 seconds), Superbank retries with exponential backoff:| Attempt | Delay | Cumulative |
|---|---|---|
| 1 | Immediate | — |
| 2 | 1 minute | 1 minute |
| 3 | 5 minutes | 6 minutes |
| 4 | 15 minutes | 21 minutes |
| 5 | 1 hour | ~1.3 hours |
| 6 | 1 day | ~1.3 days |
| 7 | 2 days | ~3.3 days |
| 8 | 4 days | ~7.3 days |
| 9 | 1 week | ~14.3 days |
| 10 | 2 weeks | ~28.3 days |
Common pitfalls
- Verify before parse. Run signature verification on the raw bytes before
JSON.parse. Frameworks that auto-parse JSON (Express default, NestJS body parser) will silently re-serialize the body and your HMAC will never match — useexpress.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 eventid(or ondata.id+ status transition). - Don’t filter by source IP. Egress IPs change without notice; rely on the signature.
Testing
Test deliveries
Test deliveries land at your endpoint with two markers your handler should expect:data.test: true— every test payload sets a top-leveltest: trueinsidedata. 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 (...001settlement request,...002outbound payment, etc.). Allow-list these prefixes if your handler validates IDs against your database.
From your local machine with ngrok
ngrok creates a public tunnel to your localhost so sandbox deliveries land directly on your dev box.From a browser with webhook.site
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.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.
Event payload reference
Thedata 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.
payment.created
payment.created
payment.updated
payment.updated
settlement_request.created and settlement_request.updated
settlement_request.created and settlement_request.updated
settlement_request.createdsettlement_request.updatedaccount.created
account.created
account.updated
account.updated
account.deleted
account.deleted
Next steps
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.