> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.redpincompany.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.redpincompany.com/_mcp/server.

# Webhooks overview

> Introduction to Redpin Webhooks

> **Info**
>
> Webhooks provide real-time notifications about referral status events directly to your system, eliminating the need for polling our API.

Our webhook service enables you to receive instant notifications for critical events in your referral workflow. This integration helps ensure immediate awareness of referral creation and processing status, allowing for real-time response to referral outcomes.

> **Tip**
>
> If you have implemented a handler for `PAYMENT STATUS` webhooks, the [webhook event simulator](/api-guide/partners/webhook-simulator) lets you exercise it against every status transition. The simulator only publishes `PAYMENT STATUS` events; it does not cover referral events.

## Webhook Events

### Referral Created Event

The `REFERRAL_CREATED` webhook event is sent when a referral is created successfully. This event helps you track the status of your referrals in real-time.

#### Event Details

**Event Name:** `REFERRAL_CREATED`

**Trigger Conditions:**

* Successful referral creation from a referral
* Failed referral creation due to validation or system errors

**Response Status:**

* `CREATED`: Referral was successfully created
* `FAILED`: Referral creation failed (includes failure message)

#### Success Payload Example

```json
{
  "partner_id": "0201110000749410",
  "additional_details": {
    "client_reference_id": "REF120536",
    "country_moving_to": "USA",
    "ccy_pair": "GBPUSD",
    "etv": "50,000 - 100,000",
    "service_required": "Other"
  },
  "contact": {
    "last_name": "Daviess1",
    "phone_number": "+614455666544",
    "mobile_number": "+447128645157",
    "first_name": "Joes2",
    "email": "usertest126@example.com",
    "date_of_birth": "1995-06-01",
    "address": {
      "street": "123 High Street",
      "city": "London",
      "post_code": "SW1A 1AA",
      "country": "UK",
      "state": ""
    }
  },
  "referral_date": "2025-05-20T19:14:05.878",
  "referral_id": "2cd722f4-c42a-4238-86fb-541575371ef8",
  "company": {
    "name": "Downweed Ltd.",
    "registration_number": "3283273"
  },
  "event_name": "REFERRAL_CREATED",
  "status": "CREATED"
}
```

#### Failure Payload Example

```json
{
  "partner_id": "0201110000749410",
  "additional_details": {
    "client_reference_id": "REF120536",
    "country_moving_to": "USA",
    "ccy_pair": "GBPUSD",
    "etv": "50,000 - 100,000",
    "service_required": "Other"
  },
  "contact": {
    "last_name": "Daviess1",
    "phone_number": "+614455666544",
    "mobile_number": "+447128645157",
    "first_name": "Joes2",
    "email": "usertest126@example.com",
    "date_of_birth": "1995-06-01",
    "address": {
      "street": "123 High Street",
      "city": "London",
      "post_code": "SW1A 1AA",
      "country": "UK",
      "state": ""
    }
  },
  "referral_date": "2025-05-20T19:14:40.021",
  "referral_id": "064dc9ed-5398-4969-bb64-f1d27a686a9e",
  "company": {
    "name": "Downweed Ltd.",
    "registration_number": "3283273"
  },
  "event_name": "REFERRAL_CREATED",
  "failure_message": "DUPLICATE_VALUE - duplicate value found- client_reference_id duplicates value on record with id- 00QUD00000EgWTG2A3",
  "status": "FAILED"
}
```

## Implementation Guide

### Authentication

Each webhook request includes a signature header to verify its authenticity. Here's how to verify the signature in different languages:

#### Java (using Svix Java SDK)

```java
Svix svix = new Svix("<YOUR_SVIX_SECRET>");
Webhook webhook = new Webhook("<YOUR_SIGNING_SECRET>");
String payload = requestBody;
String header = request.getHeader("svix-signature");
webhook.verify(payload, header); // throws exception if invalid
```

#### Node.js

```js
const { Webhook } = require("@svix/webhooks");
const webhook = new Webhook("<YOUR_SIGNING_SECRET>");
const payload = req.body;
const headers = req.headers["svix-signature"];
webhook.verify(JSON.stringify(payload), headers);
```

#### Python

```python
from svix.webhooks import Webhook
wh = Webhook("<YOUR_SIGNING_SECRET>")
headers = request.headers["svix-signature"]
payload = request.data
wh.verify(payload, headers)
```

### Best Practices

> **Warning**
>
> Always validate webhook signatures to ensure the authenticity of incoming webhook requests.

#### Integration Tips

* Set up proper error handling for webhook processing
* Implement signature verification
* Store webhook events for audit purposes
* Return 2xx status codes to acknowledge receipt

#### Implementation Steps

1. Configure Webhook Endpoint
   * Set up a publicly accessible HTTPS endpoint to receive webhook events

2. Implement Signature Verification
   * Verify the signature of each incoming webhook request using your signing secret

3. Process the Webhook
   * Parse and process the webhook payload based on the event type

4. Acknowledge Receipt
   * Return a 2xx status code to acknowledge successful receipt of the webhook

## Error Handling

### Common Failure Scenarios

* **Signature Verification Failures**:
  * Ensure you're using the raw request body for signature verification
  * Verify that all required headers are present and correctly formatted
  * Use the official Svix SDKs for reliable verification

* **Payload Processing Errors**:
  * Validate the webhook payload against the expected schema
  * Check for required fields like `customer_type`
  * Implement comprehensive error handling for malformed data

* **Server Errors (5xx)**:
  * Monitor your logs for processing errors
  * Implement proper error reporting
  * Set up alerts for repeated failures

* **Client Errors (4xx)**:
  * Verify your endpoint is properly configured
  * Check authentication credentials
  * Validate request formatting

## Retry Policy

Webhook delivery attempts follow an exponential backoff strategy:

* Maximum retries: 5 times
* Retry window: 7 days from original event
* One delivery attempt at a time
* Endpoint disabled after 5 days of continuous failures

If all attempts fail for 5 days, your endpoint will be disabled and you'll receive an EndpointDisabledEvent notification.