# FullEnrich Webhooks

## When to Use This Skill

* How do I receive FullEnrich webhooks for enrichment or reverse email lookup results?
* How do I verify the FullEnrich `X-Signature-SHA1` webhook header?
* Which secret signs FullEnrich webhooks? (Your FullEnrich API key; there is no separate webhook secret.)
* How do I handle each contact as it completes (`webhook_events.contact_finished`) versus the finished batch (`webhook_url`)?
* Why is my FullEnrich webhook signature verification failing?

## Verification (core)

FullEnrich sends `X-Signature-SHA1`: the **lowercase hex HMAC-SHA1** of the **raw request body**, keyed with your **FullEnrich API key**. The algorithm is SHA-1, not SHA-256. There is no timestamp and no prefix. Verify against the raw bytes before parsing JSON.

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

function verifyFullEnrichSignature(rawBody, signature, apiKey) {
  // Check shape first: Buffer.from(x, 'hex') silently truncates invalid hex
  if (!signature || !apiKey || !/^[0-9a-f]{40}$/i.test(signature)) return false;
  const expected = crypto.createHmac('sha1', apiKey).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature.toLowerCase()));
}

```

```python
def verify_fullenrich_signature(raw_body: bytes, signature: str | None, api_key: str) -> bool:
    expected = hmac.new(api_key.encode(), raw_body, hashlib.sha1).hexdigest()
    # Encode both sides: compare_digest raises TypeError on non-ASCII str
    return hmac.compare_digest(expected.encode(), (signature or "").lower().encode())

```

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

## Hookdeck Setup

FullEnrich signs webhooks with your FullEnrich API key. In Hookdeck, create a FullEnrich source and paste that key as the signing secret. See [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/fullenrich-webhooks/references/setup.md).

## Payloads and Statuses

FullEnrich has **no event types**. Each webhook is a per-request callback whose body mirrors the Get Enrichment Result response. Branch on the `status` field (the job state):

| `status` | Delivered via | Meaning |
| --- | --- | --- |
| `FINISHED` | `webhook_url` | The whole batch completed |
| `CANCELED` | `webhook_url` | The batch was canceled |
| `CREDITS_INSUFFICIENT` | `webhook_url` | The batch ran out of credits |
| `IN_PROGRESS` | `webhook_events.contact_finished` | One contact finished; the batch is still running (single contact in `data`) |

`CREATED` also exists as a job state but is not documented as a webhook status. Pass a `custom` object (string values) on each input to correlate results with your own IDs. See [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/fullenrich-webhooks/references/overview.md).

## Important Headers

| Header | Description |
| --- | --- |
| `X-Signature-SHA1` | Lowercase hex HMAC-SHA1 of the raw body, keyed with your API key |

## Environment Variables

```bash
FULLENRICH_API_KEY=your_fullenrich_api_key   # app.fullenrich.com/app/api

```

## Local Development

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

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/fullenrich-webhooks/references/overview.md) - Webhook parameters, statuses, payload structure, retries
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/fullenrich-webhooks/references/setup.md) - Get your API key, set webhook URLs, Hookdeck setup
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/fullenrich-webhooks/references/verification.md) - Signature details, gotchas, debugging