raindrop_redemption.completed once a booking is confirmed. What you build depends on where your points balances live: Onchain, where you are the source of truth and Rain calls you for balances and burns, or Offchain, where Rain keeps the canonical ledger and you mostly fulfill the booking. This page walks through the flow for both modes and the code recipes that go with each. For shared reference such as status values, API endpoints, and billing, see Travel Redemptions.
Partner-Managed programs skip the Rain-Managed user authorization step. A fresh balance check (webhook for onchain, DB for offchain) is the pre-commit gate before a booking, and there is no
raindrop_redemption.created webhook for partner-managed travel redemptions.Launch the travel portal
Both modes open the travel portal the same way Rain-Managed programs do: in a webview, with an encrypted session token (a JWE) that identifies the cardholder. The token recipe is identical across modes—see Launch the travel portal on the Rain-Managed page.Rain signs every webhook below with an HMAC SHA256 signature in the
Signature header, computed over the exact JSON body using your API key as the secret. Verify it before processing (see How Webhooks Work). Some tenants also receive a version field on redemption webhooks; treat it as optional and ignore any fields you don’t recognize.Partner-Managed Onchain

Partner Managed (onchain) travel redemption flow
Balance check
Rain sends a synchronousraindrop_balance.requested webhook whenever the travel portal needs to display or verify a balance. Respond within 1500ms with the cardholder’s spendable balance—confirmed points minus any you’ve already reserved for in-flight redemptions, so the portal can’t double-spend.
Request payload:
body.id is the cardholder’s Rain user ID.
Your response:
availableBalance must be a non-negative integer string of whole points. If your endpoint times out, returns non-2xx, or returns a malformed response, Rain returns 503 to the travel portal.
Booking completion
When a booking is confirmed, Rain firesraindrop_redemption.completed. Acknowledge it immediately, then burn the points in your system out of band. raindropAmount is in whole points—scale it to your token’s native units before burning.
Refund
When a booking is canceled, Rain firesraindrop_redemption.refunded so you re-credit the points. The payload carries no amount, so look up how many points you debited by body.id (the redemption ID from the completion webhook).
Webhook listener
A single endpoint handles all three. The balance check responds synchronously; the completion and refund handlers acknowledge first and process out of band.partnerOnchainWebhookListener.ts
Partner-Managed Offchain

Partner Managed (offchain) travel redemption flow
raindrop_redemption.completed, and it is informational—Rain has already debited the points by the time it fires. Use it to record the booking or trigger fulfillment in your own system.
partnerOffchainWebhookListener.ts
Webhook summary
For onchain partners,
raindrop_redemption.completed signals that you should debit or burn points in your system. For offchain partners, Rain has already debited the DB, so the webhook is informational.
Refunds
After the travel portal receives notice from the supplier (for example, a hotel or airline) that a booking was canceled and must be refunded, it sends Rain a message. Rain then re-issues the burned points to the cardholder and marks the redemptionREFUNDED. How the restored points settle depends on the mode: