# Onfido Webhooks

## When to Use This Skill

* How do I receive Onfido webhooks?
* How do I verify the Onfido `X-SHA2-Signature` header?
* How do I handle `check.completed`, `report.completed`, or `workflow_run.completed` events?
* Why is my Onfido webhook signature verification failing?
* Where do I find my Onfido webhook token?

## Verification (core)

Onfido (now Entrust Identity Verification) sends `X-SHA2-Signature`: the **lowercase hex HMAC-SHA256 of the raw request body**, keyed with the webhook's `token` (returned when the webhook is registered, also shown in Dashboard webhook management) used as a raw UTF-8 string. There is no timestamp and no prefix. Verify against the **raw** body: parsed JSON may be reordered.

Node (official `@onfido/api` SDK; throws on a bad signature):

```javascript
const { WebhookEventVerifier } = require('@onfido/api');

function verify(rawBody, signature, token) {
  try {
    return new WebhookEventVerifier(token).readPayload(rawBody, signature); // parsed event
  } catch {
    return null; // invalid signature (including malformed hex)
  }
}

```

Python (manual; Onfido's Python client has no verifier):

```python
import hmac, hashlib

def verify(raw_body: bytes, signature: str, token: str) -> bool:
    expected = hmac.new(token.encode("utf-8"), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest((signature or "").lower(), expected)

```

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

## Event Payload

Every event is `{"payload": {"resource_type", "action", "object": {...}}}`. The `action` is the event name. Studio (workflow) events also carry a top-level `resource` inside `payload`.

## Common Event Types

| `action` | Description |
| --- | --- |
| `check.started` | A check has started (Checks and Reports API) |
| `check.completed` | A check has been completed |
| `report.completed` | A report has been completed and results are available |
| `workflow_run.completed` | A Workflow Studio run has completed |
| `workflow_task.started` | A task of a workflow run has started |
| `workflow_task.completed` | A workflow task has been completed |

Webhooks are subscribed to all events by default, so also handle unknown actions gracefully. See [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/onfido-webhooks/references/overview.md) for the full list.

## Important Headers

| Header | Description |
| --- | --- |
| `X-SHA2-Signature` | Lowercase hex HMAC-SHA256 of the raw body, keyed with the webhook token |

## Environment Variables

```bash
ONFIDO_WEBHOOK_TOKEN=your_webhook_token   # `token` field of the registered webhook

```

## Local Development

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

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/onfido-webhooks/references/overview.md) - Onfido webhook concepts, events, retries
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/onfido-webhooks/references/setup.md) - Register a webhook and get the token
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/onfido-webhooks/references/verification.md) - Signature verification details and gotchas