# Middesk Webhooks

Middesk is a business identity verification (KYB) platform. It sends webhooks as business verification progresses, orders complete, and monitored businesses change.

## When to Use This Skill

* How do I receive Middesk webhooks?
* How do I verify the `X-Middesk-Signature-256` header?
* How do I handle `business.created` and `business.updated` events?
* Why is my Middesk webhook signature verification failing?
* Should I use Standard Webhooks or Svix for Middesk? (No.)

## Verification (core)

Middesk sends the **bare lowercase hex HMAC-SHA256 of the raw request body** in `X-Middesk-Signature-256`. There is no timestamp, no prefix and no signed-content template. The key is the secret you set when creating the webhook (for example `whsec_abcdef123456` or `sec_...`), used **whole as a UTF-8 string**.

This is **not** Standard Webhooks: don't use the `standardwebhooks` or `svix` libraries, and don't strip or base64-decode a `whsec_` prefix.

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

function verifyMiddeskWebhook(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  try {
    return crypto.timingSafeEqual(
      Buffer.from(signatureHeader.trim().toLowerCase()),
      Buffer.from(expected)
    );
  } catch {
    return false; // length mismatch
  }
}

```

In Express, read the raw body with `express.raw({ type: '*/*' })` so any content type verifies. Respond `400` on a bad signature and any `2xx` on success.

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

## Common Event Types

Events are delivered as `{ object: "event", id, type, data: { object }, created_at }`.

| Event | Triggered When |
| --- | --- |
| `business.created` | A Business has been created |
| `business.updated` | A Business status has changed (except when transitioning to `in_audit`) |
| `order.created` | An Order has been created for a Business |
| `order.updated` | An Order has been updated |
| `monitor.created` | A Monitor has been created for a Business |
| `monitor.updated` | A Monitor has been updated |
| `tin.retried` | A TIN retry completed successfully |
| `lien.updated` | A Lien status changed to `filed` or `open` |

Middesk has more types (agent runs, monitoring findings such as `lien.found`, `registration.created`); see [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/middesk-webhooks/references/overview.md).

## Environment Variables

```bash
MIDDESK_WEBHOOK_SECRET=whsec_abcdef123456   # The secret you set when creating the webhook

```

## Local Development

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

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/middesk-webhooks/references/overview.md) - Middesk webhook concepts, payload and event types
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/middesk-webhooks/references/setup.md) - Creating a webhook and setting the secret
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/middesk-webhooks/references/verification.md) - Signature verification details and gotchas

mTLS and OAuth (OIDC bearer token) authentication modes exist but are not covered by this skill; see [Secure webhooks](https://docs.middesk.com/build/secure-webhooks).