POST request to your endpoint with the event payload.
Event types
| Event | Session status | Trigger | Example use case |
|---|---|---|---|
session.processing | processing | Deposit detected, funds being routed | Show “payment received” to user |
session.succeeded | succeeded | Funds delivered to destination | Fulfill the order, send receipt |
session.bounced | bounced | Delivery failed, funds refunded | Alert support, notify customer |
["*"] or pick specific types.
Quickstart
1. Register an endpoint
secret. Store it securely, you’ll use it to verify that incoming requests are from Daimo.
2. Handle events
Set up a route on your server to receive webhook events:3. Send a test event
Verify your endpoint is working by sending a test event:isTestEvent: true in the payload so you can filter them out of your business logic.
Verify signatures
Every webhook delivery includes aDaimo-Signature header for verifying authenticity. Always verify signatures in production to ensure requests are from Daimo.
How it works
The signature header looks like this:- Read the raw body. Don’t parse JSON first — you need the exact bytes.
- Extract
tandv1from theDaimo-Signatureheader by splitting on,and=. - Compute HMAC-SHA256 of
${t}.${rawBody}using your webhook secret. - Compare the computed signature to
v1usingcrypto.timingSafeEqual. - Reject stale timestamps. If
tis more than 5 minutes old, discard the event to prevent replay attacks.
Full verification function
Complete handler with verification
Event payload
Field reference
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID (UUID). Use for idempotency. |
type | string | One of session.processing, session.succeeded, session.bounced |
createdAt | number | Unix timestamp (seconds) when the event was created |
data.session | object | Session snapshot at event time. Same shape as the session object, without clientSecret. |
isTestEvent | boolean | true for test events sent via /test endpoint. Omitted for real events. |
session.succeeded event:
Delivery behavior
Every delivery includes these headers:| Header | Description |
|---|---|
Content-Type | application/json |
Daimo-Signature | t=<unix_seconds>,v1=<hmac_hex> (see Verify signatures) |
- Daimo waits 10 seconds for your server to respond.
- Any 2xx status code counts as success.
- Failed deliveries are retried with exponential backoff: the n-th retry waits 2^(n-1) minutes.
- After 10 failed attempts, the event is marked as failed and no further retries are made.
Test events
UsePOST /v1/webhooks/{webhookId}/test to send a test event. You can optionally specify an eventType parameter (defaults to session.succeeded).
Test events contain isTestEvent: true in the payload. Use this flag to skip business logic during testing.
Best practices
- Return 200 quickly. Process events asynchronously if your handler does heavy work. Daimo times out after 10 seconds.
- Verify signatures. Always verify the
Daimo-Signatureheader in production to confirm requests are from Daimo. - Handle test events. Check
event.isTestEventand skip side effects (e.g. order fulfillment) for test events. - Be idempotent. Daimo may deliver the same event more than once. Log processed event IDs and skip duplicates. The
event.iduniquely identifies each event.