Developers
Decaf Disbursements API
Send money to anyone with a phone number. Recipients claim funds directly on WhatsApp.
Webhooks
Register an HTTPS endpoint to receive real-time disbursement and deposit events.
Register a Webhook
POST /v1/webhooks
{
"url": "https://yourplatform.com/webhooks/decaf",
"events": [
"disbursement.created",
"disbursement.claimed",
"disbursement.delivered",
"disbursement.failed",
"disbursement.expired",
"disbursement.cancelled",
"deposit.received",
"deposit.credited"
],
"secret": "your-signing-secret"
}Event Envelope
{
"id": "evt_xyz789",
"type": "disbursement.delivered",
"createdAt": "2026-03-05T14:10:00Z",
"data": {
"id": "dis_a1b2c3d4",
"status": "delivered",
"recipientPhone": "+527775551234",
"amountUsd": "250.00",
"reference": "payroll-march-2026-emp-042",
"payoutMethod": "bank_transfer",
"deliveredAt": "2026-03-05T14:10:00Z"
}
}Event Types
| event | trigger |
|---|---|
| disbursement.created | A disbursement is created |
| disbursement.claimed | Recipient starts claim flow |
| disbursement.delivered | Funds delivered |
| disbursement.failed | Delivery failed and refunded |
| disbursement.expired | Not claimed within 30 days |
| disbursement.cancelled | Cancelled by API |
| deposit.received | Funds hit virtual account |
| deposit.credited | Deposit confirmed and credited |
Signature Verification
X-Decaf-Signature: sha256=<hmac_hex>const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry Policy
- Attempt 1: immediate
- Attempt 2: 5 minutes
- Attempt 3: 30 minutes
- Attempt 4: 2 hours
- Attempt 5: 12 hours
Respond with 2xx within 10 seconds.