Agent skill
Zernio Webhooks Skill
Receive and verify Zernio webhooks (formerly Late, getlate.dev). Use when setting up Zernio webhook handlers, debugging X-Zernio-Signature verification, or handling social media events like post.published, post.failed, message.received, or account.disconnected.
Install this skill
npx skills add hookdeck/webhook-skills --skill zernio-webhooks
When to Use This Skill
- How do I receive Zernio webhooks?
- How do I verify the
X-Zernio-Signatureheader? - How do I handle
post.published,post.failedormessage.receivedevents? - Why is my Zernio webhook signature verification failing?
- Why am I receiving the same Zernio event twice?
Verification (core)
Zernio signs a delivery only when the endpoint has a secret, and you supply that secret when you create the endpoint (Zernio never generates one). X-Zernio-Signature is the lowercase hex HMAC-SHA256 of the raw request body keyed with that secret. X-Late-Signature is a legacy alias with the same value. There is no timestamp in the signed content.
Node:
const crypto = require('crypto');
function verify(rawBody, signatureHeader, secret) {
if (!signatureHeader || !secret) return false;
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
} catch {
return false; // different lengths
}
}
// header: req.headers['x-zernio-signature'] || req.headers['x-late-signature']
Python:
import hmac, hashlib
def verify(raw_body: bytes, signature_header: str | None, secret: str) -> bool:
if not signature_header or not secret:
return False
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature_header, expected)
Zernio has no SDK helper for verification (the docs show the manual HMAC), so all three examples verify manually. Always set a secret: an endpoint without one receives unsigned deliveries.
For complete handlers with route wiring, event dispatch, and tests, see:
Common Event Types
| Event | Description |
|---|---|
post.scheduled | A post entered the scheduled state |
post.published | The post published on every target platform |
post.partial | Published on some platforms, failed on others |
post.failed | The post failed on every target platform |
post.platform.published | One platform target finished publishing |
post.platform.failed | One platform target failed permanently |
message.received | A new inbox message (DM) arrived |
comment.received | A new comment arrived on a tracked post |
account.connected | An account was connected to a profile |
account.disconnected | A connected account stopped working or was removed |
webhook.test | Sent by POST /v1/webhooks/test regardless of subscribed events |
For the full event list (ads, calls, WhatsApp, automations and more), see Zernio webhooks and references/overview.md.
Important Headers
| Header | Description |
|---|---|
X-Zernio-Signature | Lowercase hex HMAC-SHA256 of the raw body (only when the endpoint has a secret) |
X-Late-Signature | Legacy alias, same value |
X-Zernio-Event | Event name, e.g. post.published |
X-Zernio-Event-Id | Stable event UUID, identical on retries; use as the dedupe key |
X-Late-Event-Id | Legacy alias of X-Zernio-Event-Id |
Delivery Behavior
- Return any
2xxwithin 5 seconds; persist the event and process it in the background. - Up to 7 attempts with exponential backoff (10s, 1m40s, 16m40s, 2h46m, then 24h), then a dead-letter queue.
- Delivery is at-least-once, so deduplicate on
payload.id/X-Zernio-Event-Id. payload.ididentifies the event only, never a post or account. Route byaccount.accountIdorprofiles[].externalId.
Environment Variables
ZERNIO_WEBHOOK_SECRET=your_webhook_secret # The secret you sent in POST /v1/webhooks/settings
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 zernio --path /webhooks/zernio
Reference Materials
- references/overview.md - Zernio webhook concepts and event list
- references/setup.md - Creating and testing a webhook endpoint
- references/verification.md - Signature verification details and gotchas