Flows

Notifications

Send transactional email to your users and optionally fan the same event out to your registered webhook endpoints — one call, two channels.

Send a notification

POST/v2/notifications/send
App token
Request body
user_idstringoptionalAuthorizes the call against one of your users and stamps user_id into the fan-out payload. Does NOT send email on its own
emailstringoptionalRecipient selector — the only field that triggers email. Must match one of your app's users (matched on the normalized address); mail goes to that user's stored address
subjectstring
required
Email subject
htmlstring
required
HTML body
textstringoptionalPlain-text fallback
fanout_eventstringoptionalWebhook event type to emit — use one of the five canonical events, since those plus "*" are the only values a webhook endpoint can subscribe to
payloadobjectoptionalData for the webhook event
curl
curl -X POST http://localhost:8000/v2/notifications/send \
  -H "Authorization: Bearer <app_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "trader@example.com",
    "subject": "Your account is funded",
    "html": "<h1>Congrats!</h1><p>You are now funded.</p>",
    "fanout_event": "kyc.updated",
    "payload": { "prop_account_id": "prop_123" }
  }'
200 OK
{ "email_sent": true, "webhook_deliveries_queued": 2 }

Only email sends mail

email is the only field that delivers a message. user_id does not resolve to an address — it authorizes the target user and populates user_id in the fan-out payload, so a request carrying user_id but no email returns 200 with { "email_sent": false } and sends nothing. To email a user you only know by id, look up their address first and pass it as email.

You can only email your own users

The address must belong to a user of your app, or the call fails 403 V2_NOTIFY_RECIPIENT_FORBIDDEN — prospects, support aliases and internal QA inboxes are all rejected. Delivery goes to the address stored on the user record, so the To: may differ from what you sent. Supply at least one of email, user_id or fanout_event, or the request is rejected 422 V2_NOTIFY_EMPTY.

fanout_event is not validated

The five canonical events are payment.succeeded, payment.failed, kyc.updated, payout.completed and payout.failed. This endpoint accepts any string, but fan-out matches an endpoint only on an exact name or a ["*"] subscription — so an unregistered name returns 200 with "webhook_deliveries_queued": 0, and trying to subscribe to it via /v2/webhook-endpoints fails 422 V2_WEBHOOK_UNKNOWN_EVENT.