Skip to main content
Webhooks let your server receive real-time notifications when a session transitions to a new status. Instead of polling, Daimo sends a POST request to your endpoint with the event payload.

Event types

EventSession statusTriggerExample use case
session.processingprocessingDeposit detected, funds being routedShow “payment received” to user
session.succeededsucceededFunds delivered to destinationFulfill the order, send receipt
session.bouncedbouncedDelivery failed, funds refundedAlert support, notify customer
Subscribe to all events with ["*"] or pick specific types.

Quickstart

1. Register an endpoint

The response includes a 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:
Test events include isTestEvent: true in the payload so you can filter them out of your business logic.

Verify signatures

Every webhook delivery includes a Daimo-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:
To verify a webhook:
  1. Read the raw body. Don’t parse JSON first — you need the exact bytes.
  2. Extract t and v1 from the Daimo-Signature header by splitting on , and =.
  3. Compute HMAC-SHA256 of ${t}.${rawBody} using your webhook secret.
  4. Compare the computed signature to v1 using crypto.timingSafeEqual.
  5. Reject stale timestamps. If t is more than 5 minutes old, discard the event to prevent replay attacks.

Full verification function

Complete handler with verification

Event payload

Field reference

FieldTypeDescription
idstringUnique event ID (UUID). Use for idempotency.
typestringOne of session.processing, session.succeeded, session.bounced
createdAtnumberUnix timestamp (seconds) when the event was created
data.sessionobjectSession snapshot at event time. Same shape as the session object, without clientSecret.
isTestEventbooleantrue for test events sent via /test endpoint. Omitted for real events.
Here’s an example of a session.succeeded event:

Delivery behavior

Every delivery includes these headers:
HeaderDescription
Content-Typeapplication/json
Daimo-Signaturet=<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

Use POST /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-Signature header in production to confirm requests are from Daimo.
  • Handle test events. Check event.isTestEvent and 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.id uniquely identifies each event.