Home

Webhook Setup

This guide explains how to set up and configure webhooks to receive notifications from Reap's compliance system.

Getting Started

To receive notifications when your account status changes, you need to register a webhook URL with Reap's notification system.

Available Event Types:

  • account_status_change - Notifications for account status updates including feature access changes

API Endpoints

Sandbox Environment

  • Base URL: https://sandbox-compliance.api.reap.global
  • Authentication: x-reap-api-key: your-staging-key

Production Environment

  • Base URL: https://compliance.api.reap.global
  • Authentication: x-reap-api-key: your-production-key

Webhook Operations

1. Register Your Webhook URL

Register your webhook URL to receive account status change notifications:

Using cURL:

curl -X POST <https://sandbox-compliance.api.reap.global/notification> \\
  -H "accept: application/json" \\
  -H "content-type: application/json" \\
  -H "x-reap-api-key: your-staging-key" \\
  -d '{
    "webhookUrl": "<https://your-domain.com/webhooks/reap>",
    "notificationChannel": "WEBHOOK",
    "notificationTypes": [
      "account_status_change"
    ]
  }'

Using JavaScript/Node.js:

const url = '<https://sandbox-compliance.api.reap.global/notification>';
const options = {
  method: 'POST',
  headers: {
    accept: 'application/json',
    'content-type': 'application/json',
    'x-reap-api-key': 'your-staging-key',
  },
  body: JSON.stringify({
    webhookUrl: '<https://your-domain.com/webhooks/reap>',
    notificationChannel: 'WEBHOOK',
    notificationTypes: ['account_status_change'],
  }),
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));

Expected Response:

{
  "id": "notification-id-123",
  "channel": "WEBHOOK",
  "types": ["account_status_change"],
  "config": {
    "webhook": {
      "url": "<https://your-domain.com/webhooks/reap>"
    }
  },
  "createdAt": "2024-03-20T10:00:00Z"
}

2. List Your Webhook Configurations

View all your configured webhooks:

curl -X GET <https://sandbox-compliance.api.reap.global/notification> \\
  -H "accept: application/json" \\
  -H "x-reap-api-key: your-staging-key"

3. Get a Specific Webhook Configuration

Retrieve details of a specific webhook:

curl -X GET <https://sandbox-compliance.api.reap.global/notification/{notificationId}> \\
  -H "accept: application/json" \\
  -H "x-reap-api-key: your-staging-key"

4. Update a Webhook Configuration

Update an existing webhook:

curl -X PUT <https://sandbox-compliance.api.reap.global/notification/{notificationId}> \\
  -H "accept: application/json" \\
  -H "content-type: application/json" \\
  -H "x-reap-api-key: your-staging-key" \\
  -d '{
    "webhookUrl": "<https://your-updated-domain.com/webhooks/reap>",
    "notificationChannel": "WEBHOOK",
    "notificationTypes": [
      "account_status_change"
    ]
  }'

5. Delete a Webhook Configuration

Remove a webhook configuration:

curl -X DELETE <https://sandbox-compliance.api.reap.global/notification/{notificationId}> \\
  -H "accept: application/json" \\
  -H "x-reap-api-key: your-staging-key"

Webhook Security

Signature Verification

All webhook requests from Reap include a signature in the reap-signature header. This signature is generated using RSA-SHA512 to verify the authenticity of the request.

Public Keys for Signature Validation

Staging Public Key:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsI0a/jqvSM6Z9gTLVMpD
4hLZ0n1WWuSNMwkqNH8s+E6tnBXx6nETgAJKwjdUagwgkySI74rwkCvPqVE0sm9c
iD8oi7XM+X8ybTET8fmVVG5sr12hJX5jQjjBUXzIuuqx5NJt7lFyo2yNrNzCSzuD
AhEa22Gkw43WWZoAVkNXlrfiyprKMfpjf7S4LUsRI/Y6MGyYmfm1olzYksymcaU+
2edfxoB2qZmezyEJM6CPkL2zt8UnnoS+kf/rbmHk+aKf8DW8v+XjeyQSxuclRZi/
IS589AACMygPvsO9KYzMoxmxNLrDcDnlo8+IKHQwE1RLoGC+EzJ0lDxWOEFZMRiE
xwIDAQAB
-----END PUBLIC KEY-----

Production Public Key:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5JUURpniA359qJLwB9JW
6tFAhc4ChqBiGSBaFTkgmK/XCrV8e/N7q57qq4DwymDk5+ALw8D6cKeG2QkWPDeB
n3ly96sR14+8+2GfS7z82A194V9xEpZQfjF6DeMhidFjhINAAzJHPDiM7QCk9Dh4
/Ny065vzZb0O3ek9Ivs6sbmOKXa/pGACN3k30XLkPu2XxBfeZN1rCFhdwE/wa7Bf
h5AKiA104ais19ct5uf4vNkjG5DwevFK9WiqRVxwzadOyXCk4AdksdFx8ZkOuYWh
rCdIt3Dc+pErfKIHloJ7kqA/8kiWWOP6fWbSSWrEtpLX5ieVsXnqhOYq8xA5WvEo
HwIDAQAB
-----END PUBLIC KEY-----

Signature Verification Implementation

Here's how to verify webhook signatures in your application:

Node.js Example:

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, publicKey) {
  const verifier = crypto.createVerify('RSA-SHA512');
  verifier.update(JSON.stringify(payload));
  verifier.end();

  return verifier.verify(publicKey, signature, 'base64');
}

// Use in your webhook handler
app.post('/webhooks/reap', (req, res) => {
  const signature = req.headers['reap-signature'];
  const publicKey = getPublicKeyForEnvironment(); // staging or production

  if (!verifyWebhookSignature(req.body, signature, publicKey)) {
    return res.status(401).send('Invalid signature');
  }

  // Process the webhook safely...
  console.log('Webhook verified successfully');
  res.status(200).send('OK');
});

function getPublicKeyForEnvironment() {
  // Return the appropriate public key based on your environment
  if (process.env.NODE_ENV === 'production') {
    return `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5JUURpniA359qJLwB9JW
6tFAhc4ChqBiGSBaFTkgmK/XCrV8e/N7q57qq4DwymDk5+ALw8D6cKeG2QkWPDeB
n3ly96sR14+8+2GfS7z82A194V9xEpZQfjF6DeMhidFjhINAAzJHPDiM7QCk9Dh4
/Ny065vzZb0O3ek9Ivs6sbmOKXa/pGACN3k30XLkPu2XxBfeZN1rCFhdwE/wa7Bf
h5AKiA104ais19ct5uf4vNkjG5DwevFK9WiqRVxwzadOyXCk4AdksdFx8ZkOuYWh
rCdIt3Dc+pErfKIHloJ7kqA/8kiWWOP6fWbSSWrEtpLX5ieVsXnqhOYq8xA5WvEo
HwIDAQAB
-----END PUBLIC KEY-----`;
  } else {
    return `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsI0a/jqvSM6Z9gTLVMpD
4hLZ0n1WWuSNMwkqNH8s+E6tnBXx6nETgAJKwjdUagwgkySI74rwkCvPqVE0sm9c
iD8oi7XM+X8ybTET8fmVVG5sr12hJX5jQjjBUXzIuuqx5NJt7lFyo2yNrNzCSzuD
AhEa22Gkw43WWZoAVkNXlrfiyprKMfpjf7S4LUsRI/Y6MGyYmfm1olzYksymcaU+
2edfxoB2qZmezyEJM6CPkL2zt8UnnoS+kf/rbmHk+aKf8DW8v+XjeyQSxuclRZi/
IS589AACMygPvsO9KYzMoxmxNLrDcDnlo8+IKHQwE1RLoGC+EzJ0lDxWOEFZMRiE
xwIDAQAB
-----END PUBLIC KEY-----`;
  }
}

Python Example:

import json
import base64
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

def verify_webhook_signature(payload, signature, public_key_pem):
    try:
        # Load the public key
        public_key = serialization.load_pem_public_key(public_key_pem.encode())

        # Decode the signature
        signature_bytes = base64.b64decode(signature)

        # Verify the signature
        public_key.verify(
            signature_bytes,
            json.dumps(payload, separators=(',', ':')).encode(),
            padding.PKCS1v15(),
            hashes.SHA512()
        )
        return True
    except Exception:
        return False

# Use in your Flask webhook handler
@app.route('/webhooks/reap', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('reap-signature')
    public_key = get_public_key_for_environment()

    if not verify_webhook_signature(request.json, signature, public_key):
        return 'Invalid signature', 401

    # Process the webhook safely...
    print('Webhook verified successfully')
    return 'OK', 200

Webhook Requirements & Limitations

Technical Requirements

  • HTTPS Required: Your webhook URL must use HTTPS
  • Response Time: Respond with 200 OK within 5 seconds
  • Response Format: Simple 200 OK status code (response body is ignored)

Rate Limits & Constraints

  • Webhook Limit: Each business is limited to 10 webhook configurations
  • Retry Policy: Reap will retry failed webhook deliveries with exponential backoff
  • Timeout: Requests will timeout after 5 seconds

Security Best Practices

  1. Always verify signatures before processing webhook data
  2. Use HTTPS for your webhook endpoints
  3. Validate incoming data structure and content
  4. Log webhook events for debugging and audit purposes
  5. Implement idempotency to handle duplicate deliveries
  6. Secure your API keys and rotate them regularly

Testing Your Webhook

1. Webhook URL Validation

Ensure your webhook endpoint:

  • Returns 200 OK for POST requests
  • Handles JSON payloads correctly
  • Responds within 5 seconds
  • Implements signature verification

2. Test Endpoint Example

// Simple test endpoint
app.post('/webhooks/reap', (req, res) => {
  console.log('Received webhook:', JSON.stringify(req.body, null, 2));
  console.log('Headers:', req.headers);

  // Always verify signature in production
  const signature = req.headers['reap-signature'];
  if (signature && !verifyWebhookSignature(req.body, signature, publicKey)) {
    return res.status(401).send('Invalid signature');
  }

  res.status(200).send('OK');
});

3. Testing Checklist

  • Webhook URL is accessible via HTTPS
  • Endpoint returns 200 OK for valid requests
  • Signature verification is implemented and working
  • Error handling is in place for invalid signatures
  • Logging is configured for debugging
  • Webhook registration via API is successful

Troubleshooting

Common Issues

Webhook Not Receiving Events

  • Verify webhook URL is correctly registered
  • Check that your endpoint is accessible from the internet
  • Ensure HTTPS is properly configured
  • Confirm you're subscribed to the correct event types (e.g., account_status_change)

Signature Verification Failing

  • Verify you're using the correct public key for your environment
  • Ensure you're signing the raw JSON payload (not parsed object)
  • Check that the signature header name is exactly reap-signature
  • Verify RSA-SHA512 algorithm is being used

Webhook Timeouts

  • Ensure your endpoint responds within 5 seconds
  • Consider processing webhooks asynchronously
  • Implement proper error handling

Getting Help

If you encounter issues setting up webhooks:

  1. Check your webhook logs for error messages
  2. Verify API key permissions for your environment
  3. Test with a simple endpoint first
  4. Contact support with webhook registration details and error logs

For additional support, include:

  • Your webhook URL
  • The notification ID from registration
  • Error messages or logs
  • Environment (staging/production)