Webhook Event Reference
Event Delivery Guarantees
- At-least-once delivery — Aelix may deliver the same event more than once. Your handler must be idempotent
- Ordering — Events are delivered in approximate chronological order but not guaranteed to be strictly ordered
- Retention — Failed deliveries are retried for up to 72 hours
Event Envelope
{
"event_id": "evt_abc123",
"type": "payment.completed",
"created_at": "2025-04-15T14:32:00Z",
"api_version": "2025-04-01",
"data": {
"object": { ... } // The resource that changed
}
}
Payment Events
| Event | Trigger |
|---|---|
| payment.created | Payment instruction received |
| payment.pending_clearance | Payment submitted to payment rail |
| payment.completed | Funds successfully settled |
| payment.failed | Payment rejected or returned |
| payment.cancelled | Payment cancelled before submission |
Account Events
| Event | Trigger |
|---|---|
| account.created | New account opened |
| account.updated | Account details changed |
| account.suspended | Account temporarily suspended |
| account.closed | Account permanently closed |
Transaction Events
| Event | Trigger |
|---|---|
| transaction.posted | Transaction recorded on ledger |
| transaction.reversed | Transaction reversed or refunded |
Deduplicating Events
const processed = new Set();
async function handleWebhook(event) {
if (processed.has(event.event_id)) return;
processed.add(event.event_id);
// Store event_id in your DB for persistent deduplication
await db.webhookEvents.upsert({ id: event.event_id, processed_at: new Date() });
switch (event.type) {
case 'payment.completed': await handlePaymentCompleted(event.data.object); break;
case 'account.created': await handleAccountCreated(event.data.object); break;
}
}