Guide to Census (Fivetran Activations) Webhooks: Features and Best Practices
Census (Fivetran Activations) webhooks tell your systems what is happening to your reverse-ETL syncs: a sync run is queued, starts, succeeds or fails, or a sync alert is raised or resolved. Census is now part of Fivetran, which sells it as Fivetran Activations. It moves data from your warehouse into business tools, and these Sync Lifecycle Webhooks are how you hook its sync status into your own alerting, orchestration or reporting.
This guide covers how Census webhooks are configured and signed, the events and payloads, what the documentation leaves out, and the best practices for running a Census receiver in production.
What are Census webhooks?
Census webhooks are configured per workspace. Each webhook has a name, an endpoint and the events it subscribes to. When a subscribed event happens, Census sends a small JSON payload that identifies the workspace, the sync and the sync run, and names the event.
Every request carries an X-Signature header, a base64 HMAC-SHA256 of the raw body keyed with the webhook's secret. The secret is shown once, when you create the webhook.
Census's documentation now lives at fivetran.com under Activations, and the alert payloads in those docs still link to app.getcensus.com. These webhooks are separate from Fivetran's connector webhooks, which use a different header (X-Fivetran-Signature-256) and a hex signature. If you receive both, verify them separately.
Census webhook features
| Feature | Details |
|---|---|
| Configuration | Workspace settings, Webhooks tab, or the Activations webhooks REST API |
| Subscription model | One or more events per webhook |
| Signature header | X-Signature |
| Scheme | HMAC-SHA256, standard base64 |
| Signed content | The raw request body only |
| Secret | One per webhook, shown once at creation |
| Replay window | None. No timestamp is sent or signed |
| Event ID | None |
| HTTP method and content type | Not stated in the docs. The examples are JSON bodies |
| Timeout and retries | Not documented |
| Source IPs | Not published |
Common events
Census has two groups of events:
| Group | Event | Fires when |
|---|---|---|
| Sync alerts | sync.alert.raised | Any subscribed sync alert in your workspace is triggered |
sync.alert.resolved | Any subscribed sync alert is resolved | |
| Sync runs | sync.triggered | A sync run has been queued |
sync.started | Active work on the sync run has started | |
sync.completed | The sync run has completed, successfully or not | |
sync.success | A sync run completed successfully | |
sync.failed | A sync run failed |
Every payload is a flat object. These fields are always present:
{
"workspace_id": 3167,
"sync_id": 3167956,
"sync_run_id": 324402082,
"event": "sync.failed"
}
sync.completed adds status, which is ok for a successful run and emergency for a failed one. The alert events add alert_instance_id, alert_type (for example FailureAlertConfiguration), message, details and followup_url, a link to the sync's history in the Census app. Here is Census's sync.alert.raised example, with the docs' line wrapping removed:
{
"workspace_id": 3167,
"sync_id": 3167956,
"sync_run_id": 324402082,
"alert_instance_id": 626248,
"alert_type": "FailureAlertConfiguration",
"message": "Sync Failed",
"details": "Sync has failed with error: A mapped source column has been deleted: email",
"followup_url": "https://app.getcensus.com/workspaces/3167/syncs/3167956/sync-history",
"event": "sync.alert.raised"
}
The IDs are integers. Because sync.completed, sync.success and sync.failed overlap, subscribing to all three gives you two events at the end of every run. Pick sync.completed with its status field, or the sync.success and sync.failed pair.
Setting up Census webhooks
- In Census (Fivetran Activations), open Workspace settings and go to the Webhooks tab.
- Click Add Webhook.
- Enter a Name, an optional Description and the Endpoint URL, and subscribe to at least one event.
- Click Create. Copy the one-time secret straight away and store it server-side, for example as
CENSUS_WEBHOOK_SECRET. Census won't show it again.
You can also list and manage webhooks through the Activations REST API.
If you use Hookdeck, create a source with the Census source type, set the secret on it, and use the Hookdeck source URL as the endpoint.
Securing Census webhooks
Compute an HMAC-SHA256 of the raw request body, using the secret's bytes as the key, encode it as standard base64, and compare it in constant time with X-Signature. This follows Census's own Python sample.
const crypto = require('crypto');
const express = require('express');
function verifyCensusSignature(rawBody, signatureHeader, secret) {
if (!signatureHeader || !secret) return false;
const expected = Buffer.from(crypto.createHmac('sha256', secret).update(rawBody).digest('base64'), 'utf8');
const received = Buffer.from(signatureHeader.trim(), 'utf8');
return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}
const app = express();
app.post('/webhooks/census', express.raw({ type: '*/*' }), (req, res) => {
if (!verifyCensusSignature(req.body, req.get('x-signature'), process.env.CENSUS_WEBHOOK_SECRET)) {
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString('utf8'));
// Route on event.event, then process async.
res.sendStatus(200);
});
The same check in Python:
import base64
import hashlib
import hmac
import os
def verify_census_signature(raw_body: bytes, signature_header, secret: str) -> bool:
if not signature_header or not secret:
return False
expected = base64.b64encode(hmac.new(secret.encode("utf-8"), raw_body, hashlib.sha256).digest())
return hmac.compare_digest(signature_header.strip().encode("utf-8"), expected)
# In FastAPI: raw_body = await request.body()
# verify_census_signature(raw_body, request.headers.get("x-signature"),
# os.environ["CENSUS_WEBHOOK_SECRET"])
Census's sample passes the header straight to hmac.compare_digest, which raises a TypeError when the header is missing. The version above returns False instead.
To check your verifier, use the secret census-test-secret and this exact body:
{"workspace_id":3167,"sync_id":3167956,"sync_run_id":324399613,"event":"sync.success"}
The X-Signature header should be:
UIrFwdyskAsq/9SV2lnvbrVt51aBHJVV4QO4vXp+U7E=
Make Census webhooks production-ready. Hookdeck Event Gateway verifies the
X-Signatureheader on every Census request and durably queues sync alerts and run events, so a sync failure is never missed because your alerting service was down.
Census webhook limitations and pain points
Delivery behaviour is undocumented
The Problem: You don't know how long Census waits for a response, whether it retries, or what counts as a failure.
Why It Happens: The Sync Lifecycle Webhooks page documents the events, payloads and signature, but nothing about timeouts, retries or ordering. It doesn't even name the HTTP method.
Workarounds:
- Respond with a
2xxquickly, and assume a slow or failed response may mean a lost event. - Reconcile from the sync history in Census, or its API, for any sync that matters.
How Hookdeck Can Help: Hookdeck accepts each request as soon as Census sends it and stores it, then retries delivery to your service on a schedule you set, so your own downtime doesn't depend on a retry policy you can't see.
The secret is shown once
The Problem: You can't verify deliveries because the secret wasn't saved.
Why It Happens: Census shows the secret only when you click Create.
Workarounds:
- Copy it into your secret store before closing the dialog.
- If it is lost, create a new webhook and delete the old one.
How Hookdeck Can Help: Set the secret on the Hookdeck source once, and every service behind Hookdeck receives verified events without needing the secret itself.
No event ID
The Problem: You can't tell a duplicate delivery from a new event.
Why It Happens: Payloads carry the workspace, sync and run IDs and the event name, but no ID for the event or the delivery.
Workarounds:
- Use
sync_run_idpluseventas the idempotency key for run events. - For alerts, use
alert_instance_idplusevent.
How Hookdeck Can Help: Hookdeck's deduplication can drop repeated requests before they reach your service, based on the fields you choose, such as sync_run_id and event.
Overlapping completion events
The Problem: Your alerting fires twice for every failed sync.
Why It Happens: A failed run produces sync.completed with status: "emergency" and sync.failed, and a sync alert can add sync.alert.raised on top.
Workarounds:
- Subscribe to only one of the completion styles.
- Use alert events for paging, and run events for metrics, rather than both for the same purpose.
How Hookdeck Can Help: Hookdeck filters can route sync.failed and sync.alert.raised to different destinations, so each event goes where it's needed.
Best practices
Verify against the raw body
The signature covers the exact bytes Census sent. Read the raw body (express.raw(), await request.body()) and parse only after verification.
Route on event
The payload's event field names the event. Switch on it, and log and acknowledge anything you don't recognise.
Fetch details from Census
Run events only carry IDs. When you need row counts, errors or timing, look up the sync run in Census using sync_id and sync_run_id, or send people to followup_url from alert events.
Acknowledge fast and process asynchronously
Return a 2xx as soon as the event is verified and stored, and do the rest afterwards. See why to process webhooks asynchronously.
Deduplicate deliveries
Use sync_run_id with event, or alert_instance_id with event, as an idempotency key. See our guide to webhook idempotency.
Conclusion
Census signs its Sync Lifecycle Webhooks with a base64 HMAC-SHA256 of the raw body in X-Signature, keyed with a secret you only see once. Save the secret when you create the webhook, verify against the raw bytes, deduplicate on sync_run_id and event, and choose one way of detecting completion. Census doesn't document its delivery behaviour, so plan for reconciliation.
Hookdeck Event Gateway sits in front of your receiver, verifies every Census signature, and holds each sync event until your service has processed it.
Get started with Hookdeck for free and handle Census webhooks reliably in minutes.