Understanding Webhooks
Webhooks are automated HTTP callbacks that NextAPI sends to your server when events occur. Instead of polling the API for status updates, you receive instant notifications.
How Webhooks Work
Event occurs → NextAPI creates webhook payload → HTTP POST to your endpoint → You acknowledge
NextAPI signs each delivery so you can verify it came from us, not a malicious third party.
Webhook Payload Structure
NextAPI webhook events come in two shapes depending on the event category.
v2-prefixed events (payment instrument, payment intent) use event + payload:
{
"event": "v2.payment_intent.succeeded",
"payload": {
"id": "...",
"account_id": "...",
"amount": 150000,
"external_id": "order-98765",
"status": "succeeded"
}
}
Payout events use type + data:
{
"type": "payout_request.processed",
"data": {
"id": "...",
"source_account_id": "...",
"amount_cents": 50000,
"status": "completed"
}
}
| Field | Description |
|---|---|
event | Event name for v2.* events (e.g., v2.payment_intent.succeeded) |
type | Event name for payout events (e.g., payout_request.processed) |
payload | The resource data for v2.* events |
data | The resource data for payout events |
Event Types
Payment Events (v2-prefixed)
These events use event.event and event.payload.
| Event | Description |
|---|---|
v2.payment_intent.succeeded | Payment received and settled |
v2.payment_intent.canceled | Payment intent cancelled |
v2.payment_instrument.used | Funding Method instrument used (single-use instruments) |
v2.payment_instrument.payment_received | Incoming payment received (Funding Method) |
v2.payment_instrument.payment_settled | Incoming payment cleared (Funding Method) |
Payout Events
These events use event.type and event.data.
| Event | Description |
|---|---|
payout_request.creation_failed | Payout request failed to create |
payout_request.queued | Payout request queued for settlement |
payout_request.queue_failed | Payout request failed to queue |
payout_request.processed | Payout request fully processed |
payout.succeeded | Individual payout delivered |
payout.failed | Individual payout failed |
payout.processed | Individual payout processing complete |
payout.processing_failed | Individual payout processing failed |
Platform Events
These events use event.type and event.data.
| Event | Description |
|---|---|
deposit.confirmed | Inbound deposit confirmed on an account |
direct_transfer.received | Direct transfer received by an account |
legal_entity.verification_status_changed | Merchant KYC/compliance verification status updated |
Delivery and Retries
NextAPI retries failed deliveries with exponential backoff:
| Attempt | Delay | Cumulative Wait |
|---|---|---|
| 1 | Immediate | — |
| 2 | 1 minute | 1 minute |
| 3 | 5 minutes | 6 minutes |
| 4 | 30 minutes | 36 minutes |
| 5 | 2 hours | ~2.5 hours |
Response expectations:
- 2xx — Success. Webhook processed, no retry.
- 4xx — Client error. No retry (fix your endpoint).
- 5xx — Server error. Retry scheduled.
Your endpoint must respond within 30 seconds or the delivery is considered failed.
Idempotency
Webhook events may be delivered more than once. Always use the id field to deduplicate:
- Store processed event IDs
- Before processing, check if the event ID was already handled
- Skip duplicates
This prevents double-processing (e.g., crediting an account twice for the same payment).
Security
NextAPI delivers webhooks through Svix. Every delivery is signed using three headers: svix-id, svix-timestamp, and svix-signature. Always verify these using the Svix SDK before processing an event — do not re-implement the HMAC algorithm manually.
The webhook secret is returned in whsec_<base64> format when you create a webhook. Svix enforces a 5-minute timestamp tolerance automatically, so replay attacks are handled for you.
For implementation details, see Verify Webhook Signatures and Setup Webhooks.
Related
- Setup Webhooks — implementation guide with code
- The Lifecycle of a Payout — events that trigger payout webhooks
- Wallet Structure — understand the accounts that emit events