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

# Webhook Integration

> Set up and consume webhooks from IllumiChat

Webhooks let IllumiChat notify your systems in real time when events occur, such as a new chat message, a ticket being created, or a lead being captured. Instead of polling the API, your server receives an HTTP POST request for each event.

## How Webhooks Work

<Steps>
  <Step title="Register a webhook">
    Provide a URL and select the events you want to receive.
  </Step>

  <Step title="Events occur">
    When a subscribed event happens in IllumiChat, a payload is sent to your URL.
  </Step>

  <Step title="Your server processes the event">
    Your endpoint receives the POST request, verifies it, and takes action.
  </Step>
</Steps>

## Setting Up a Webhook

### Via the Dashboard

1. Go to **Settings > Webhooks** in your workspace
2. Click **Create Webhook**
3. Enter your endpoint URL (must be HTTPS)
4. Select the events you want to subscribe to
5. Save

### Via the API

```bash theme={null}
curl -X POST https://app.illumichat.com/api/webhooks \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/illumichat",
    "events": ["chat.message.created", "ticket.created", "lead.captured"],
    "active": true
  }'
```

## Event Types

| Event                  | Description                              |
| ---------------------- | ---------------------------------------- |
| `chat.message.created` | A new message was sent in a conversation |
| `chat.session.created` | A new chat session started               |
| `ticket.created`       | A support ticket was created             |
| `ticket.updated`       | A ticket status or assignment changed    |
| `lead.captured`        | A lead was captured from the widget      |
| `contact.created`      | A new contact was added                  |

## Payload Format

Every webhook delivery includes a JSON payload with a consistent structure:

```json theme={null}
{
  "event": "ticket.created",
  "timestamp": "2025-06-15T14:30:00Z",
  "workspaceId": "ws_abc123",
  "data": {
    "id": "tkt_xyz789",
    "subject": "Cannot reset my password",
    "status": "open",
    "priority": "medium",
    "createdAt": "2025-06-15T14:30:00Z"
  }
}
```

| Field         | Type     | Description                                   |
| ------------- | -------- | --------------------------------------------- |
| `event`       | `string` | The event type                                |
| `timestamp`   | `string` | ISO 8601 timestamp of when the event occurred |
| `workspaceId` | `string` | The workspace where the event originated      |
| `data`        | `object` | Event-specific payload                        |

## Handling Webhooks

### Basic Express Server

```javascript theme={null}
const express = require("express");
const app = express();

app.use(express.json());

app.post("/webhooks/illumichat", (req, res) => {
  const { event, data } = req.body;

  switch (event) {
    case "ticket.created":
      console.log("New ticket:", data.subject);
      // Create a Jira issue, send a Slack notification, etc.
      break;

    case "lead.captured":
      console.log("New lead:", data.email);
      // Add to CRM, send welcome email, etc.
      break;

    case "chat.message.created":
      console.log("New message in session:", data.sessionId);
      break;

    default:
      console.log("Unhandled event:", event);
  }

  // Always return 200 quickly to acknowledge receipt
  res.status(200).json({ received: true });
});

app.listen(3000);
```

### Next.js API Route

```typescript theme={null}
// app/api/webhooks/illumichat/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  const body = await request.json();
  const { event, data } = body;

  switch (event) {
    case "ticket.created":
      await handleNewTicket(data);
      break;
    case "lead.captured":
      await handleNewLead(data);
      break;
  }

  return NextResponse.json({ received: true });
}

async function handleNewTicket(data: any) {
  // Your ticket handling logic
}

async function handleNewLead(data: any) {
  // Your lead handling logic
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Respond quickly">
    Return a `200` response as soon as possible. Process the event asynchronously if your logic takes more than a few seconds. IllumiChat may time out and retry if your endpoint does not respond promptly.
  </Accordion>

  <Accordion title="Handle duplicates">
    Webhook deliveries can occasionally be duplicated. Use the event `timestamp` and resource `id` to deduplicate on your end.

    ```javascript theme={null}
    const processedEvents = new Set();

    function handleWebhook(payload) {
      const key = `${payload.event}:${payload.data.id}:${payload.timestamp}`;
      if (processedEvents.has(key)) return;
      processedEvents.add(key);
      // Process the event
    }
    ```
  </Accordion>

  <Accordion title="Use HTTPS">
    Webhook URLs must use HTTPS. For local development, use a tunneling service like ngrok to expose your local server.

    ```bash theme={null}
    ngrok http 3000
    # Use the generated https://xxxx.ngrok.io/webhooks/illumichat URL
    ```
  </Accordion>

  <Accordion title="Log payloads during development">
    Log the full payload while building your integration so you can inspect the exact structure of each event type.

    ```javascript theme={null}
    app.post("/webhooks/illumichat", (req, res) => {
      console.log(JSON.stringify(req.body, null, 2));
      res.status(200).json({ received: true });
    });
    ```
  </Accordion>
</AccordionGroup>

## Retry Policy

If your endpoint returns a non-2xx status code or times out, IllumiChat retries the delivery with exponential backoff:

| Attempt   | Delay      |
| --------- | ---------- |
| 1st retry | 1 minute   |
| 2nd retry | 5 minutes  |
| 3rd retry | 30 minutes |

After 3 failed retries, the delivery is marked as failed. You can view failed deliveries in your webhook settings and manually trigger a re-delivery.

## Managing Webhooks

### List Active Webhooks

```bash theme={null}
curl https://app.illumichat.com/api/webhooks \
  -H "Authorization: Bearer <your-token>"
```

### Disable a Webhook

```bash theme={null}
curl -X PATCH https://app.illumichat.com/api/webhooks/{webhookId} \
  -H "Authorization: Bearer <your-token>" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'
```

### Delete a Webhook

```bash theme={null}
curl -X DELETE https://app.illumichat.com/api/webhooks/{webhookId} \
  -H "Authorization: Bearer <your-token>"
```

<Tip>
  Use webhooks together with the [Contacts API](/api/authentication) and [Tickets](/features/tickets) to build automated support workflows — for example, automatically creating a CRM record when a lead is captured and escalating to a human agent when a ticket is created.
</Tip>
