# Kustomer Webhooks

## When to Use This Skill

* How do I receive Kustomer outbound webhooks?
* How do I verify the `X-Kustomer-Webhook-Signature` header?
* How do I handle `kustomer.conversation.create` or `kustomer.message.create` events?
* Why is my Kustomer webhook signature verification failing?
* Why did Kustomer turn my outbound webhook off?

## Verification (core)

Kustomer signs the **raw request body** with HMAC-SHA256, keyed with the webhook's secret (the `token` field from `POST /v1/outbound-webhooks`, also shown in **Settings > Platform > Outbound webhooks > Edit > Header Information**). The lowercase hex digest is sent in `X-Kustomer-Webhook-Signature`. There is no timestamp and no prefix. Kustomer has no webhook SDK, so verification is manual.

Node:

```javascript
const crypto = require('crypto');

function verify(rawBody, signatureHeader, secret) {
  if (!signatureHeader) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
  } catch {
    return false; // different lengths
  }
}

```

Python:

```python
import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    if not signature_header:
        return False
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature_header.encode(), expected.encode())

```

Read the body as raw bytes (`express.raw({ type: '*/*' })`) so any content type verifies.

> **For complete handlers with route wiring, event dispatch, and tests**, see:
> 
> * [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/kustomer-webhooks/examples/express/)
> * [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/kustomer-webhooks/examples/nextjs/)
> * [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/kustomer-webhooks/examples/fastapi/)

## Common Event Types

The event type is the `name` field in the JSON body (there is no event-type header).

| Event | Description |
| --- | --- |
| `kustomer.conversation.create` | Conversation created |
| `kustomer.conversation.update` | Conversation updated |
| `kustomer.customer.create` | Customer created |
| `kustomer.customer.update` | Customer updated |
| `kustomer.message.create` | Message created |
| `kustomer.message.update` | Message updated |
| `kustomer.team.create` / `kustomer.team.update` | Team created / updated |
| `kustomer.user.create` / `kustomer.user.update` | User created / updated |

> **For payload samples**, see [Kustomer outbound webhooks](https://developer.kustomer.com/kustomer-apps-platform/docs/outbound-webhooks)

## Important Headers

| Header | Description |
| --- | --- |
| `X-Kustomer-Webhook-Signature` | Hex HMAC-SHA256 of the raw body |

## Environment Variables

```bash
KUSTOMER_WEBHOOK_SECRET=your_webhook_token   # "token" of the outbound webhook

```

## Local Development

```bash
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 kustomer --path /webhooks/kustomer

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/kustomer-webhooks/references/overview.md) - Kustomer webhook concepts and payload shape
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/kustomer-webhooks/references/setup.md) - Configuration guide
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/kustomer-webhooks/references/verification.md) - Signature verification details