Automation: Webhooks & Translations
Configure once, runs automatically. Stream consent events to your backend and serve the banner in regional languages required by the DPDP Act.
Webhooks
Webhooks push consent-lifecycle events to your backend the moment they happen, so you can keep CRMs, analytics, support tools, and audit systems in sync without polling.
Events
| Event | Fired when |
|---|---|
| purpose.granted | The user grants consent for a purpose (banner or layered prompt). |
| purpose.denied | The user explicitly denies consent for a purpose. |
| purpose.withdrawn | The user withdraws a previously granted consent (via preferences modal or DSR). |
| purpose.expired | A consent record passes its retention window and is auto-expired. |
Setup
- 1Go to Admin → Cookies → Automation → Webhooks and click Add Webhook.
- 2Paste your endpoint URL (must be
https://) and tick the events you want to receive. - 3On save, a one-time signing secret is shown. Copy it and store it as an env var on your backend — you cannot retrieve it later.
- 4Use the Send test event button on the webhook row to verify your endpoint is wired correctly.
Payload shape
POST https://your-endpoint.com/privacy-labs
Content-Type: application/json
X-PrivacyLabs-Event: purpose.granted
X-PrivacyLabs-Timestamp: 1714915200
X-PrivacyLabs-Signature: sha256=<hex-hmac-sha256>
{
"event": "purpose.granted",
"timestamp": 1714915200,
"data": {
"purposeKey": "marketing_emails",
"sessionId": "...",
"platform": "web",
"occurredAt": "2026-05-07T11:22:33.123Z"
}
}Verifying the signature (recommended)
Compute an HMAC-SHA256 over <timestamp>.<raw-body> using your signing secret, and compare it (constant-time) against the hex value after sha256= in the X-PrivacyLabs-Signature header. Reject anything older than 5 minutes to block replay attacks.
import crypto from 'crypto';
function verify(rawBody, headers, secret) {
const timestamp = headers['x-privacylabs-timestamp'];
const sigHeader = headers['x-privacylabs-signature']; // "sha256=<hex>"
const received = sigHeader.replace('sha256=', '');
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex');
const ageSec = (Date.now() / 1000) - Number(timestamp);
if (ageSec > 300) return false; // 5 minute replay window
return crypto.timingSafeEqual(
Buffer.from(expected, 'hex'),
Buffer.from(received, 'hex')
);
}Retries & auto-disable
- Any non-2xx response is treated as a failure. We retry with exponential back-off.
- Respond 200 OK within 5 seconds. We don't wait longer than that.
- After 10 consecutive failures, the webhook is auto-disabled and shown as such in the dashboard. Re-enable it once your endpoint is healthy.
- Handlers should be idempotent — the same event may be delivered more than once after retries. Use
data.recordIdas the dedupe key.
HTTPS only. Plain HTTP endpoints are rejected at save time. Use a real cert (not self-signed) — many cloud webhooks won't trust self-signed CAs.
Translations
The DPDP Act requires consent notices to be available in the user's regional language (Eighth Schedule). Add languages once — the banner auto-detects the user's locale and shows the right one.
Workflow
- 1Go to Admin → Cookies → Automation → Translations and pick the languages you need from the chips.
- 2Click Generate Translations. The engine translates every banner string from your English source.
- 3Open each language row, click Edit, and review. Saving promotes the status from auto-translated to reviewed.
- 4Toggle Active on the languages you want live. The SDK begins serving them immediately to matching users.
When the source text changes
If you edit your English banner copy (title, description, button labels) the existing translations don't update automatically. Use the Re-translate All button to refresh every language from the latest English source. Your manual edits will be overwritten, so do this when you genuinely want a fresh translation.
What gets translated
All visible banner strings: title, description, accept/settings/save buttons, withdraw-consent link, privacy-policy link, and the four standard category names with descriptions (essential, performance, analytics, marketing).
Purpose names and descriptions you define under Consent Data are translated separately at the purpose level. (Recommended: write purpose copy in clear, neutral English; the auto-translator handles regional variants better that way.)