# Census Webhooks

Census is now Fivetran Activations (getcensus.com redirects to fivetran.com). Its sync lifecycle webhooks tell your systems when a reverse ETL sync is queued, running, finished, failed, or alerting. This is separate from the [fivetran-webhooks](/webhooks/skills/fivetran-webhooks) skill, which covers Fivetran's REST API webhooks (`X-Fivetran-Signature-256`, hex).

## When to Use This Skill

* How do I receive Census (Fivetran Activations) webhooks?
* How do I verify the `X-Signature` header on a Census webhook?
* How do I handle `sync.completed`, `sync.success`, `sync.failed`, or `sync.alert.raised` events?
* Why is my Census webhook signature verification failing?
* How do I trigger downstream jobs or alerts when a Census sync finishes or fails?

## Verification (core)

Census signs the **raw request body** with HMAC-SHA256, keyed with the one-time secret shown when you create the webhook (used as raw bytes, no `whsec_` handling), and sends the digest as **standard base64** (not hex) in `X-Signature`. There is no timestamp and no prefix.

Node:

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

function verify(rawBody, signatureHeader, secret) {
  if (!signatureHeader || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('base64');
  try {
    return crypto.timingSafeEqual(Buffer.from(signatureHeader.trim()), Buffer.from(expected));
  } catch {
    return false; // different lengths
  }
}

```

Python:

```python
import base64, hmac, hashlib

def verify(raw_body: bytes, signature_header: str | None, secret: str) -> bool:
    if not signature_header or not secret:
        return False
    expected = base64.b64encode(
        hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
    ).decode()
    return hmac.compare_digest(signature_header.strip(), expected)

```

In Express, read the body with `express.raw({ type: '*/*' })` so the bytes are intact whatever `Content-Type` is sent.

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

## Common Event Types

The event name is in the JSON body (`event`); there is no event-type header. Every payload has `workspace_id`, `sync_id`, `sync_run_id`, and `event`.

| Event | Description |
| --- | --- |
| `sync.triggered` | A sync run has been queued |
| `sync.started` | Active work on the sync run has started |
| `sync.completed` | The run finished, successful or not; `status` is `ok`, or `emergency` if it failed |
| `sync.success` | The run completed successfully |
| `sync.failed` | The run failed |
| `sync.alert.raised` | A subscribed sync alert fired (adds `alert_instance_id`, `alert_type`, `message`, `details`, `followup_url`) |
| `sync.alert.resolved` | A subscribed sync alert was resolved (same extra fields) |

> **For the full reference**, see [Sync lifecycle webhooks](https://fivetran.com/docs/activations/syncs/sync-monitoring/sync-lifecycle-webhooks).

## Important Details

| Item | Value |
| --- | --- |
| Signature header | `X-Signature` |
| Algorithm | HMAC-SHA256 of the raw body, standard base64 |
| Secret | Shown **once** when the webhook is created; copy it then |
| Setup | Webhooks tab in the workspace (Add Webhook), or the Census API |
| Test event | The docs don't describe one; accept and log unknown `event` values after verifying |

## Environment Variables

```bash
CENSUS_WEBHOOK_SECRET=your_webhook_secret   # One-time secret shown when the webhook is created

```

## Local Development

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

```

## Reference Materials

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/census-webhooks/references/overview.md) - Census webhook concepts and payloads
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/census-webhooks/references/setup.md) - Creating a webhook and getting the secret
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/census-webhooks/references/verification.md) - Signature verification details