# Wiza Webhooks

Wiza is a B2B contact data platform. When a contact lookup (an individual reveal) completes, Wiza
POSTs the result as JSON to your webhook URL. Webhooks are **not signed**. Every request carries an
`x-auth-key` header containing a SHA-256 hash of your Wiza API key, and your endpoint authenticates
the request by recomputing that hash and comparing.

## When to Use This Skill

* How do I receive Wiza webhooks?
* How do I verify the `x-auth-key` header on a Wiza webhook?
* Does Wiza sign webhook payloads? (No: it sends a hash of your API key)
* How do I handle `individual_reveal` results, finished or failed?
* Why does my Wiza webhook endpoint return 401 after I rotated the API key?

## Verification (core)

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

function verifyWizaRequest(headers, apiKey = process.env.WIZA_API_KEY) {
  if (!apiKey) return false;                       // never accept when unconfigured
  const received = headers['x-auth-key'];          // lowercase hex SHA-256 of the API key
  if (!received) return false;
  const expected = crypto.createHash('sha256').update(apiKey, 'utf8').digest('hex');
  const a = Buffer.from(received, 'utf8');
  const b = Buffer.from(expected, 'utf8');
  return a.length === b.length && crypto.timingSafeEqual(a, b);  // lengths first: it throws otherwise
}

```

* Header: `x-auth-key: <lowercase hex SHA-256 of your API key>` (header name is case-insensitive).
  Compare the whole value; nothing is stripped or prefixed.
* Python: `hmac.compare_digest(received.encode(), expected.encode())`. Pass bytes, never `str`,
  which raises `TypeError` on non-ASCII input.
* Return `401` on a missing header or mismatch, `400` for a body that isn't a JSON object, `200`
  once handled. Non-2xx responses are retried up to 3 times.
* Read the body raw (`express.raw({ type: '*/*' })`) and authenticate before parsing it.
* **This is a static shared credential.** It is the same on every request. It authenticates the
  sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS and
  rotate the credential if it leaks. Rotating the Wiza API key changes the header value, so update
  your configuration at the same time.

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

## Event Types

The payload is `{ status: { code, message }, type, data }`; there is no top-level `id` (the
reveal's id is `data.id`). The `type` documented for webhooks is
`individual_reveal`; `status.code` says how the lookup ended.

| `type` | `status.code` | Meaning |
| --- | --- | --- |
| `individual_reveal` | `200` | The reveal finished; `data` holds the result |
| `individual_reveal` | `400` | The reveal failed |

## Environment Variables

```bash
WIZA_API_KEY=your-wiza-api-key   # Settings > API

```

The examples hash this key and compare the digest with `x-auth-key`.

### Using Hookdeck

Enter the lowercase hex SHA-256 hash of your Wiza API key, as sent in `x-auth-key`, not the API key
itself. Compute it with:

```bash
printf %s "$WIZA_API_KEY" | sha256sum
# or
node -e "console.log(require('crypto').createHash('sha256').update(process.env.WIZA_API_KEY).digest('hex'))"

```

## Local Development

Wiza can't reach `localhost`. Tunnel with the Hookdeck CLI (no account required):

```bash
npx hookdeck-cli listen 3000 wiza --path /webhooks/wiza

```

Use the printed URL as the webhook URL in Wiza.

## Resources

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/wiza-webhooks/references/overview.md) - What Wiza webhooks are, payload shape and delivery
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/wiza-webhooks/references/setup.md) - Set the webhook URL and compute the hash for Hookdeck
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/wiza-webhooks/references/verification.md) - x-auth-key check details, gotchas, debugging 401s
* [examples/](https://github.com/hookdeck/webhook-skills/tree/main/skills/wiza-webhooks/examples/) - Runnable Express, Next.js and FastAPI handlers with tests