Appearance
Delivery Semantics
Webhooks provide at-least-once delivery. This means:
- Every event will be delivered to your endpoint at least once
- In rare cases (network issues, timeouts), the same event may be delivered more than once
- Your handler must be idempotent - use the
event_idfield to deduplicate (see Idempotency)
Ordering and Batching
- Events may be batched per webhook and are delivered in order
- Each delivery is a JSON payload containing one or more events
- On failure, the entire batch is retried while maintaining order. You won't receive later events until earlier events have been processed successfully
Retry Behaviour
The platform considers the delivery successful if your endpoint responds with a 2xx status code.
If your endpoint does not respond with a 2xx status code, the platform retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | 1 minute |
| 2 | 2 minutes |
| 3 | 4 minutes |
| 4 | 8 minutes |
| 5 | 16 minutes |
| 6+ | 32 minutes (cap) |
Retries continue indefinitely until a successful delivery. Your endpoint must return a 2xx response to acknowledge receipt - any other status code (including 3xx redirects) is treated as a failure.
Acknowledging Events
Return a 200 OK (or any 2xx) response as quickly as possible. Process the event payload asynchronously if your handling logic is slow. The platform does not inspect the response body.
Idempotency
Because webhooks use at-least-once delivery, your handler should deduplicate events by event_id. A simple approach:
- Before processing an event, check if you have already handled its
event_id - If yes, skip it and return
200 OK - If no, process the event and record the
event_idas handled
javascript
async function handleWebhook(events) {
for (const event of events) {
const already_processed = await db.exists("processed_events", event.event_id);
if (already_processed) continue;
await processEvent(event);
await db.insert("processed_events", { id: event.event_id });
}
}This ensures that duplicate deliveries do not cause duplicate side effects (e.g. crediting a wallet twice).