> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corsa.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks - Real-Time Compliance Event Notifications

> Receive real-time webhook notifications for alerts, cases, clients, and transactions from the Corsa platform.

## How to Add a Webhook

Your system can register to events on the Corsa platform you want to be notified about and act upon.

1. From the **Settings → Developers** menu, choose the **Webhooks** tab and press **+ Add webhook**.
2. Choose the events you want to receive webhooks for (choose at least one).
3. Specify your server URL and a secret for validation on your server.

## Webhook Handling

### Headers

When receiving webhooks, inspect the following HTTP headers:

| Header                | Description                                                                        |
| --------------------- | ---------------------------------------------------------------------------------- |
| `x-hook-delivery`     | A unique identifier for this specific delivery attempt.                            |
| `x-hook-id`           | The unique identifier of the webhook configuration that sent this request.         |
| `x-hook-event`        | The type of event that triggered the webhook (e.g., `individual_client.created`).  |
| `x-hub-signature-256` | The HMAC SHA256 signature of the request payload, used for verifying authenticity. |
| `x-request-id`        | Request trace ID for debugging and correlating logs.                               |
| `x-request-origin`    | Origin of the request that triggered the event (`WEB` or `API`).                   |

### Verifying Signatures

It's crucial to verify the signature of incoming webhooks to ensure they originated from the Corsa API and were not tampered with. Use the `verifyWebhookSignature` function exported from the SDK.

```typescript theme={null}
import { verifyWebhookSignature } from '@corsa-labs/sdk';

async function verifyWebhookRequest(request: Request) {
  const signature = request.headers.get('x-hub-signature-256');
  const payload = await request.text();
  const secret = process.env.WEBHOOK_SECRET;

  if (!signature || !secret) {
    console.error("Missing signature or secret");
    return false;
  }

  const isValid = verifyWebhookSignature(secret, payload, signature);

  if (!isValid) {
    console.error('Invalid webhook signature');
    return false;
  }

  console.log("Webhook signature verified successfully!");
  return true;
}
```

### Event Types

The following webhook event types are available (defined in `WebhookEventType`):

#### Clients

| Event Type                  | Description                                     |
| --------------------------- | ----------------------------------------------- |
| `individual_client.created` | Triggered when an individual client is created. |
| `individual_client.updated` | Triggered when an individual client is updated. |
| `corporate_client.created`  | Triggered when a corporate client is created.   |
| `corporate_client.updated`  | Triggered when a corporate client is updated.   |

#### Alerts & Cases

| Event Type      | Description                                                                               |
| --------------- | ----------------------------------------------------------------------------------------- |
| `alert.created` | Triggered when an alert is created.                                                       |
| `alert.updated` | Triggered when an alert is updated (e.g., status change, assignment, priority change).    |
| `case.created`  | Triggered when a case is created.                                                         |
| `case.updated`  | Triggered when a case is updated (e.g., status change, assignment, investigation update). |

#### Transactions

| Event Type            | Description                                                    |
| --------------------- | -------------------------------------------------------------- |
| `transaction.created` | Triggered when a transaction is created.                       |
| `transaction.updated` | Triggered when a transaction is updated (e.g., status change). |

#### Financial Operations

| Event Type           | Description                                       |
| -------------------- | ------------------------------------------------- |
| `deposit.created`    | Triggered when a deposit operation is created.    |
| `deposit.updated`    | Triggered when a deposit operation is updated.    |
| `withdrawal.created` | Triggered when a withdrawal operation is created. |
| `withdrawal.updated` | Triggered when a withdrawal operation is updated. |
| `trade.created`      | Triggered when a trade operation is created.      |
| `trade.updated`      | Triggered when a trade operation is updated.      |

#### Members

| Event Type                  | Description                                                                        |
| --------------------------- | ---------------------------------------------------------------------------------- |
| `individual_member.created` | Triggered when an individual member (e.g., beneficial owner, director) is created. |
| `individual_member.updated` | Triggered when an individual member is updated.                                    |
| `corporate_member.created`  | Triggered when a corporate member (e.g., subsidiary, parent company) is created.   |
| `corporate_member.updated`  | Triggered when a corporate member is updated.                                      |

#### Financial Instruments

| Event Type                  | Description                                                                   |
| --------------------------- | ----------------------------------------------------------------------------- |
| `blockchain_wallet.created` | Triggered when a blockchain wallet is created.                                |
| `blockchain_wallet.updated` | Triggered when a blockchain wallet is updated (e.g., risk assessment change). |
| `bank_account.created`      | Triggered when a bank account is created.                                     |
| `bank_account.updated`      | Triggered when a bank account is updated.                                     |
| `payment_account.created`   | Triggered when a payment account (PIX, CLABE, mobile money, etc.) is created. |
| `payment_account.updated`   | Triggered when a payment account is updated.                                  |

#### Checklists

| Event Type          | Description                                              |
| ------------------- | -------------------------------------------------------- |
| `checklist.created` | Triggered when a checklist is created for an entity.     |
| `checklist.updated` | Triggered when a checklist or checklist item is updated. |

#### Attachments

| Event Type           | Description                                                          |
| -------------------- | -------------------------------------------------------------------- |
| `attachment.created` | Triggered when a file attachment is uploaded or linked to an entity. |
| `attachment.updated` | Triggered when an attachment's metadata is updated.                  |
| `attachment.deleted` | Triggered when an attachment is deleted.                             |

#### Forms

| Event Type                            | Description                             |
| ------------------------------------- | --------------------------------------- |
| `form_template.public_form_submitted` | Triggered when a client submits a form. |

The payload structure for each event type (`WebhookEvent`, `EntityCreatedPayload`, `EntityUpdatedPayload`) and the `WebhookEventType` enum can be imported from `@corsa-labs/sdk`.

For detailed payload structures for each event type, see the [Event Payloads](/webhooks/event-payloads) reference.

For a practical example of how to set up a webhook handler, see the [Webhook Example](/sdk/webhook-example).

### Retries & Failure Handling

Corsa retries failed webhook deliveries automatically. A queued delivery attempt is considered failed if your endpoint returns a non-2xx status code or does not respond within **5 seconds**.

| Queued attempt | Delay after previous attempt |
| -------------- | ---------------------------- |
| 1 (initial)    | Immediate                    |
| 2              | 10 seconds                   |
| 3              | 10 seconds                   |
| 4              | 10 seconds                   |

After the initial attempt and three queued retries fail, the delivery is marked as failed. Redirects are not followed, so your endpoint must return a `2xx` response directly.

Because retries can deliver the same event more than once, your handler should be **idempotent** — use the `x-hook-delivery` header as a unique key to deduplicate events on your side.

### Signing Secret

The signing secret is a shared string used to verify that incoming webhook requests are authentic and have not been tampered with or spoofed. This ensures that the request is genuinely coming from the Corsa server. Make sure the signing secret you provide is stored securely and encrypted in your platform (for example, using AWS Secrets Manager).

We use HMAC-based shared-key authentication. The signing process involves generating a signature using the shared key and comparing it with the one included in the webhook request.

```typescript theme={null}
const signingSecret: string = '<the secret>';
const algorithm = 'sha256';
const result = `${algorithm}=${createHmac(algorithm, signingSecret)
    .update(payload)
    .digest('hex')}`;

// >>> console.log(result)
// sha256=4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865
```

The result is attached in the request headers under the `X-Hub-Signature-256` header:

```
X-Hub-Signature-256: sha256=4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865
```

On your end, validate by using the same implementation (hashing the HTTP request body) and compare the result with the header. For increased security, use a cryptographically-secure string comparison function like `crypto.timingSafeEqual`.
