Webhooks
Webhooks overview
Webhooks are how every async state change reaches your system. Treat them as the source of truth, never poll for status if you can avoid it.
Register an endpoint
Webhooks are how every async state change reaches your system. Treat them as the source of truth, never poll for status if you can avoid it.
curl $XPEND_BASE/v1/webhooks/endpoints \
-H "Authorization: Bearer $XPEND_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/xpend",
"event_types": ["payment_intent.completed", "payout.completed"]
}'Event shape
{
"id": "evt_01HXY...",
"type": "payment_intent.completed",
"created_at": "2026-05-11T13:21:04Z",
"data": {
"payment_intent": {
"id": "pi_01HXY...",
"amount": "150.00",
"chain": "ethereum",
"token": "USDC",
"status": "completed",
"metadata": { "order_id": "order_8421" }
}
}
}Supported event types
| Event | Description |
|---|---|
| payment_intent.completed | Funds credited for a payment intent. |
| payment_intent.failed | Permanent failure on a payment intent. |
| payment_intent.expired | Intent TTL elapsed without settlement. |
| payout.completed | Outbound funds executed on-chain. |
| payout.failed | Outbound funds rejected or reverted. |
| balance.updated | Per-asset settlement balance changed. |
Managing endpoints
Disable an endpoint with PATCH/v1/webhooks/endpoints/:id, rotate the secret with POST/v1/webhooks/endpoints/:id/rotate-secret. Keep one active secret per endpoint in your secret manager.
Inspecting deliveries
GET/v1/webhooks/deliveries returns recent delivery attempts with status, response codes, and bodies, useful for debugging integration drift in live.
Webhooks are the source of truth
Alert on webhook failure rate and payout failure statuses. Pair with dashboard monitoring and payout failure alerts.