Webhooks
Webhooks for transaction and RFI updates, with signature verification
Overview
We send webhooks to your configured webhook URL when there is an update to a transaction or an RFI (Request for Information). Webhooks apply to both parent and sub-accounts.
To configure your webhook URL, see Update Webhook URL — only available in sandbox mode.
All webhooks are sent as POST requests with the following headers:
Every webhook is signed. Verify the Pave-Signature header as described in Verifying Webhook Signatures.
Available Webhook Events
Transaction
A webhook is sent every time a transaction is created or transitions to a new status — whether it's money moving between your accounts or incoming/outgoing transfers. Each unique status of a transaction triggers at most one webhook, so you will not receive duplicates for the same status.
Body:
Call Get Transaction to retrieve the complete transaction data, including its current status.
Request for Information (RFI)
See RFI Webhook for the payload format and examples.
Responding to Webhooks
Your webhook handler should respond with a 2xx status code to acknowledge receipt.
| Response | Result |
|---|---|
2xx | Delivered successfully |
4xx | Permanent failure, not retried |
5xx, timeout, connection error | Retried with exponential backoff |
Retry Policy
Failed deliveries are retried with exponential backoff (factor 2.0), starting with a 10-second delay between attempts and doubling after each failure (10s → 20s → 40s → 80s, etc.), capped at 10 minutes between attempts.
Retries continue for up to 72 hours, after which the webhook will no longer be attempted.
Verifying Webhook Signatures
Pave secures webhook payloads using ECDSA (Elliptic Curve Digital Signature Algorithm) signatures.
Each webhook request includes a cryptographic signature in the Pave-Signature header that allows you to verify the authenticity and integrity of the payload.
Header Format
The Pave-Signature header contains a timestamp and signature in the following format:
Where:
timestamp: Unix timestamp of when the signature was generatedsignature: Base64-encoded ECDSA signature of the signed payload
Signature Payload Construction
The signed payload is constructed by concatenating the raw response body with the timestamp:
Example:
- Response body:
{"transaction_id": "123456"} - Timestamp:
1234567890 - Signed payload:
{"transaction_id": "123456"}1234567890
Raw Body Requirement
The response body must be processed as a raw buffer to ensure signature verification succeeds.
JSON parsing or other transformations can alter the byte representation of the payload, causing verification to fail.
Example of problematic transformation: