Skip to main content

Handling Webhooks

Receive real-time notifications when events occur in your account. Webhooks are delivered via HTTP POST to your endpoint.

Webhook Structure

All webhook events use this envelope:
{
  "event": "cardaccount.transaction.created",
  "id": "7dd3a60c-b0f3-416f-aacc-b64661a3a909",
  "time": "2023-01-10T00:57:38.585Z",
  "data": {
    // Event-specific payload
  }
}
Fields:
  • event: Event type identifier
  • id: Unique event ID (use for deduplication)
  • time: ISO 8601 timestamp
  • data: Event-specific payload
See Webhook Events for complete event catalog.

Signature Verification

Webhooks include an RSA-SHA256 signature in the x-access-signature header. Verify signatures using the webhook public key. Header: x-access-signature
Algorithm: RSA-SHA256
Key: Public key provided when creating webhook endpoint
Verification Process:
  1. Extract signature from x-access-signature header (Base64-encoded)
  2. Load webhook public key (PEM format)
  3. Verify signature against raw request body using RSA-SHA256 with PKCS1v15 padding
  4. Return HTTP 401 if verification fails
Important:
  • Use raw request body before JSON parsing
  • Signature is Base64-encoded
  • Public key is provided at webhook creation time
For language-specific verification examples, see the Recipes section.

Endpoint Requirements

Your webhook endpoint must:
  • Accept POST requests over HTTPS
  • Return HTTP 200 within 5 seconds
  • Parse JSON request bodies
  • Verify signatures before processing
Response: Return HTTP 200 immediately after signature verification. Process events asynchronously if needed.

Event Processing

Deduplication

Use the id field to detect duplicate deliveries. Store processed event IDs and check before processing. Storage options:
  • Database table with event ID index
  • Distributed cache (Redis) with TTL
  • In-memory set (development only)
TTL: 24-48 hours (events won’t be redelivered after this period)

Async Processing

Process events asynchronously to meet the 5-second response requirement:
  1. Verify signature
  2. Check for duplicate (event ID)
  3. Acknowledge with HTTP 200
  4. Queue event for async processing
Queue options: Message queues (Redis, RabbitMQ, AWS SQS), background jobs, or event buses.

Error Handling

  • Log errors without preventing acknowledgment
  • Implement retry logic in your queue/worker
  • Make handlers idempotent (safe to retry)

Webhook Statuses

Webhooks transition through these statuses:
StatusDescription
createdNewly created, pending initial health check
healthyActive, deliveries successful
unhealthyDegraded, retries in progress
errorSuspended due to repeated failures
removedDeleted from system
Status transitions:
  • createdunhealthyhealthy (on first success)
  • healthyunhealthy (on failures)
  • unhealthyerror (after 10+ consecutive failures)
  • errorhealthy (on successful auto-recovery ping)
  • errorremoved (after 24 hours of failed pings)
See Webhooks Overview for detailed lifecycle.

Testing

Local Development

Use tunneling tools to expose local endpoints:
  • ngrok
  • Cloudflare Tunnel
  • localtunnel
Configure the tunnel URL as your webhook endpoint in the dashboard.

Test Events

Send test events from the dashboard:
  1. Navigate to SettingsWebhooks
  2. Select your endpoint
  3. Click Send Test Event
  4. Choose event type

Monitoring

Log:
  • Event ID and type
  • Processing status
  • Errors and latency
  • Full payload (for debugging)
Monitor:
  • Success rate
  • Processing latency
  • Queue depth (if using queues)
  • Endpoint availability

Troubleshooting

Webhooks not arriving:
  • Verify HTTPS endpoint is publicly accessible
  • Check firewall rules
  • Confirm endpoint URL in dashboard
Signature verification failing:
  • Verify correct public key
  • Use raw body before JSON parsing
  • Check Base64 encoding
Duplicate events:
  • Normal behavior (retries)
  • Implement deduplication using event ID

Next Steps