Skip to main content
Webhooks notify your server when events happen — user KYC status changes, card transactions, and collateral updates.

Setup

Configure your webhook endpoint using the Set Webhook endpoint. You’ll receive a webhookSecret (prefixed whsec_) that you’ll use to verify webhook signatures.

Events

KYC Events

EventDescription
user.kyc.pendingUser KYC submission received, under review
user.kyc.approvedUser KYC approved — user can now create cards
user.kyc.deniedUser KYC denied
user.kyc.needsVerificationAdditional verification required from the user
user.kyc.manualReviewKYC submitted for manual review

Transaction Events

EventDescription
transaction.authorizedCard transaction authorized
transaction.declinedCard transaction declined
transaction.reversedCard transaction reversed
transaction.settledCard transaction settled (final)

Collateral Events

EventDescription
collateral.receivedCollateral deposit received
collateral.settledCollateral deposit settled

Payload Format

All webhooks are delivered as POST requests with a JSON body:
{
  "event": "user.kyc.approved",
  "timestamp": "2025-01-15T10:30:00.000Z",
  "data": {
    "serviceId": "acme-rain-user-abc123def456ghi",
    "partnerId": "acme",
    "status": "approved",
    "details": {}
  }
}

Signature Verification

Every webhook includes an X-Webhook-Signature header containing an HMAC-SHA256 hex digest. Always verify this signature before processing the webhook.
const crypto = require('crypto');

function verifyWebhook(req, webhookSecret) {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Retry Policy

If your endpoint doesn’t respond with a 2xx status code, the webhook is retried with exponential backoff:
AttemptDelay
1st retry5 minutes
2nd retry30 minutes
3rd retry2 hours
After 3 failed retries, the webhook is marked as failed. All webhook deliveries (successful and failed) are logged for debugging.
Your webhook endpoint must respond within 30 seconds. Long-running processing should be handled asynchronously after acknowledging the webhook with a 200 response.