# Flagsmith Webhooks

## When to Use This Skill

* How do I receive Flagsmith webhooks?
* How do I verify the `X-Flagsmith-Signature` header?
* How do I handle `FLAG_UPDATED`, `FLAG_DELETED` or `AUDIT_LOG_CREATED` events?
* How do I receive Flagsmith identity webhooks (flag evaluations per user)?
* Why is my Flagsmith webhook signature verification failing?

## Essential Code (USE THIS)

Flagsmith signs a webhook only if you set a **Secret** when adding it (the secret is optional). When set, every request carries `X-Flagsmith-Signature`: the **hex** HMAC-SHA256 of the **raw request body** (UTF-8), keyed with the secret (UTF-8). The scheme is the same for environment, identity and audit-log webhooks. There is no timestamp and it is not Standard Webhooks.

### Verification (JavaScript)

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

function verifyFlagsmithSignature(rawBody, signatureHeader, secret) {
  if (!rawBody || !signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  const received = Buffer.from(signatureHeader.trim().toLowerCase());
  const expectedBuf = Buffer.from(expected);
  return received.length === expectedBuf.length && crypto.timingSafeEqual(received, expectedBuf);
}

// Express: mount the route with express.raw({ type: '*/*' }) so the signed bytes are untouched.

```

### Verification (Python)

```python
import hashlib, hmac

def verify_flagsmith_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected.encode(), signature_header.strip().lower().encode())

```

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

## Payload Shapes

Environment and audit-log webhooks wrap the data in `{ "event_type": "...", "data": {...} }`. Identity webhooks have **no** `event_type`; they send the evaluation for one identity.

| Event / payload | Webhook type | Triggered when |
| --- | --- | --- |
| `FLAG_UPDATED` | Environment | A flag's state or value changes (`data.new_state`, `data.previous_state`) |
| `FLAG_DELETED` | Environment | A flag is deleted |
| `AUDIT_LOG_CREATED` | Audit log (organisation) | Any admin action is logged (`data.log`, `data.related_object_type`) |
| `{ identity, flags, traits, segments }` | Identity | The Get Identity Flags endpoint evaluates an identity |

Flagsmith's open-source code also emits `NEW_VERSION_PUBLISHED` (feature versioning v2) which the docs don't list; handle unknown `event_type` values with a 200.

## Important Headers

| Header | Description |
| --- | --- |
| `X-Flagsmith-Signature` | Hex HMAC-SHA256 of the raw body; sent only when a secret is set |
| `Content-Type` | `application/json` (don't depend on it; read the raw body for any type) |

## Environment Variables

```bash
FLAGSMITH_WEBHOOK_SECRET=your_webhook_secret   # The "Secret" you enter when adding the webhook

```

## Local Development

```bash
# Forward Flagsmith webhooks to your local server (no account required)
npx hookdeck-cli listen 3000 flagsmith --path /webhooks/flagsmith

```

Paste the Hookdeck URL into the webhook URL field in Flagsmith.

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/flagsmith-webhooks/references/overview.md) - Webhook types, events, payloads
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/flagsmith-webhooks/references/setup.md) - Add webhooks and a secret in Flagsmith
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/flagsmith-webhooks/references/verification.md) - Signature verification details and gotchas