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

# Webhooks Overview

> Real-time event notifications for your KYC workflows

Webhooks allow you to receive real-time HTTP notifications when events occur in your KYC workflows. Instead of polling the API for updates, webhooks push data to your server automatically.

## How Webhooks Work

```mermaid theme={null}
sequenceDiagram
    participant User
    participant KYC API
    participant SNS
    participant Your Server
    
    User->>KYC API: Complete session step
    KYC API->>SNS: Publish event
    SNS->>Your Server: POST webhook
    Your Server->>SNS: 200 OK
```

1. **Event Occurs**: A user completes a session, a document is processed, or a status changes
2. **Event Published**: The event is published to our internal message queue
3. **Webhook Delivered**: Your configured endpoint receives a signed HTTP POST request
4. **Acknowledgment**: Your server responds with `2xx` to confirm receipt

## Webhook Categories

<CardGroup cols={2}>
  <Card title="Session Webhooks" icon="user-check" href="/api-reference/webhooks/sessions">
    Real-time notifications for session lifecycle events: creation, completion, processing results, and status changes.
  </Card>

  <Card title="Watchlist Webhooks" icon="radar" href="/api-reference/watchlists">
    Alerts when ongoing monitoring detects new matches or status changes for monitored subjects.
  </Card>
</CardGroup>

## Webhook Security

All webhooks are signed using **HMAC-SHA256** to ensure authenticity. See [Signature Verification](/api-reference/webhooks/sessions#signature-verification) for implementation details.

### Security Headers

Every webhook request includes:

| Header                | Description                                       |
| --------------------- | ------------------------------------------------- |
| `X-Webhook-ID`        | Unique event ID for idempotency (`evt_abc123...`) |
| `X-Webhook-Timestamp` | Unix timestamp when event was created             |
| `X-Webhook-Signature` | HMAC-SHA256 signature (`sha256=...`)              |
| `User-Agent`          | `KYC-Webhooks/1.0`                                |
| `Content-Type`        | `application/json`                                |

## Configuration

Configure webhooks in your tenant settings via the API or dashboard:

```bash theme={null}
curl -X PATCH https://kyc.legaltalent.ai/kyc/tenants/me/notification-channels \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://your-server.com/webhooks/kyc",
    "notification_emails": ["alerts@yourcompany.com"]
  }'
```

<Info>
  When you set a `webhook_url` without providing a `webhook_secret`, a secure secret is automatically generated for you. The secret is returned masked in API responses (e.g., `****************************a1b2`).
</Info>

## Webhook Envelope

All webhooks share a common envelope structure:

```json theme={null}
{
  "id": "evt_abc123def456",
  "type": "kyc.session.processed",
  "created": 1735228800,
  "data": {
    // Event-specific payload
  }
}
```

| Field     | Type    | Description                                |
| --------- | ------- | ------------------------------------------ |
| `id`      | string  | Unique event ID - use for idempotency      |
| `type`    | string  | Event type (e.g., `kyc.session.processed`) |
| `created` | integer | Unix timestamp of event creation           |
| `data`    | object  | Event-specific payload                     |

## Best Practices

<AccordionGroup>
  <Accordion title="Respond Quickly">
    Return a `2xx` response within 10 seconds. Process webhook data asynchronously if needed.

    ```python theme={null}
    @app.post("/webhooks/kyc")
    async def handle_webhook(request: Request, background_tasks: BackgroundTasks):
        payload = await request.json()
        
        # Acknowledge immediately
        background_tasks.add_task(process_webhook, payload)
        return {"received": True}
    ```
  </Accordion>

  <Accordion title="Implement Idempotency">
    Use the `X-Webhook-ID` header to deduplicate events. Store processed event IDs to avoid reprocessing.

    ```python theme={null}
    def handle_webhook(event_id: str, payload: dict):
        if redis.sismember("processed_events", event_id):
            return  # Already processed
        
        # Process the event
        process_event(payload)
        
        # Mark as processed (with TTL for cleanup)
        redis.sadd("processed_events", event_id)
        redis.expire("processed_events", 86400 * 7)  # 7 days
    ```
  </Accordion>

  <Accordion title="Verify Signatures">
    Always verify the webhook signature before processing. See [Signature Verification](/api-reference/webhooks/sessions#signature-verification).
  </Accordion>

  <Accordion title="Handle Retries">
    Webhooks may be retried if your server doesn't respond with `2xx`. Design your handlers to be idempotent.
  </Accordion>

  <Accordion title="Use HTTPS">
    Always use HTTPS endpoints for production webhooks. HTTP endpoints are only allowed in development.
  </Accordion>
</AccordionGroup>

## Retry Policy

<Warning>
  If your endpoint fails to respond with `2xx`, the webhook will **not** be automatically retried. Ensure your endpoint is reliable and responds quickly.
</Warning>

For critical workflows, we recommend:

* Monitoring your webhook endpoint uptime
* Using a queue-based architecture for processing
* Implementing fallback polling for missed events

## Testing Webhooks

### Local Development

Use tools like [ngrok](https://ngrok.com) to expose your local server:

```bash theme={null}
ngrok http 3000
# Use the generated URL as your webhook_url
```

### Webhook Testing Endpoint

You can use the staging environment to test webhooks without affecting production data.

## Notification Channels

In addition to webhooks, you can configure:

| Channel     | Description                                      |
| ----------- | ------------------------------------------------ |
| **Webhook** | HTTP POST to your endpoint with signed payloads  |
| **Email**   | Email notifications to configured addresses      |
| **Slack**   | Rich notifications to Slack channels via webhook |

Configure multiple channels in your tenant settings:

```json theme={null}
{
  "webhook_url": "https://your-server.com/webhooks/kyc",
  "webhook_secret": "whsec_...",
  "notification_emails": ["alerts@company.com", "compliance@company.com"],
  "slack_webhook_url": "https://hooks.slack.com/services/..."
}
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Session Webhooks" icon="arrow-right" href="/api-reference/webhooks/sessions">
    Learn about session lifecycle events and payloads
  </Card>

  <Card title="Configure Tenant" icon="gear" href="/api-reference/tenants">
    Set up your webhook URL and notification channels
  </Card>
</CardGroup>
