Agent skill
Iterable Webhooks Skill
Receive and authenticate Iterable system webhooks. Use when setting up an Iterable webhook endpoint, checking the Authorization header (Bearer or Basic), debugging 401s, or handling Iterable events such as emailSend, emailOpen, emailClick, emailBounce and emailUnSubscribe.
Install this skill
npx skills add hookdeck/webhook-skills --skill iterable-webhooks
Iterable (marketing automation) sends system webhooks to your server whenever an event occurs anywhere in a project: email sends, opens, clicks and bounces, SMS, push, in-app, journey exits and more. Payloads are not signed. The only authentication is the Authorization header, if you choose Basic or OAuth 2.0 on the webhook.
When to Use This Skill
- How do I receive Iterable webhooks?
- How do I verify the Iterable webhook
Authorizationheader (Bearer or Basic)? - Does Iterable sign webhook payloads? (No: static credential header only)
- Why does my Iterable webhook endpoint return 401?
- How do I handle
emailSend,emailOpen,emailClick,emailBounceoremailUnSubscribe?
Verification (core)
On the system webhook, set Authentication to Basic or OAuth 2.0 and fill in Authentication Token. Iterable then sends the credential as the Authorization header:
- OAuth 2.0:
Authorization: Bearer <token>(you enter only the token) - Basic: exactly the text you typed, e.g.
Authorization: Basic abc123(not necessarily base64user:pass)
Store the whole header value, prefix included, as ITERABLE_AUTHORIZATION and compare the whole Authorization header to it. Don't strip or parse the prefix and never decode a Basic value:
const crypto = require('crypto');
// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
const ha = crypto.createHash('sha256').update(String(a)).digest();
const hb = crypto.createHash('sha256').update(String(b)).digest();
return crypto.timingSafeEqual(ha, hb);
}
function verifyIterableRequest(headers, expected = process.env.ITERABLE_AUTHORIZATION) {
if (!expected) return false; // never accept when unconfigured
const received = headers['authorization']; // full value, e.g. "Bearer abc123"
return Boolean(received) && safeEqual(received, expected);
}
Return 401 when this fails. Python uses hmac.compare_digest on bytes (encode both sides; str raises on non-ASCII). Read the body raw (express.raw({ type: '*/*' })) and parse JSON only after the check. See references/verification.md.
A static shared credential authenticates the sender, not the body, and gives no replay protection (no signature, no timestamp). Use HTTPS (Iterable requires it) and rotate the credential if it leaks.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Types
The body has eventName, email (or userId) and a dataFields object. Names are case-sensitive and exactly as Iterable sends them, including emailUnSubscribe:
eventName | Fires when |
|---|---|
emailSend | A blast or triggered email is sent |
emailOpen | A recipient opens an email |
emailClick | A recipient clicks a link |
emailBounce | An email bounces (dataFields.recipientState) |
emailComplaint | A recipient reports spam |
emailSubscribe / emailUnSubscribe | Subscription changes (universal to all channels) |
smsSend, pushSend, inAppOpen, webPushSend, whatsAppSend, rcsSend | Other channels |
journeyExit | A user exits a journey |
The full list is in references/overview.md.
Delivery
2-second timeout; retries up to 3 times only on 429, 502, 503, 504 (other 4xx/5xx, including 401, are not retried). Delivery is not guaranteed, order is not guaranteed and duplicates are possible: respond fast, queue the work, and deduplicate.
Environment Variables
ITERABLE_AUTHORIZATION=Bearer 00000000-0000-0000-0000-000000000000 # full header value
Local Development
npx hookdeck-cli listen 3000 iterable --path /webhooks/iterable
No account required. Use the printed URL as the Endpoint URL (Iterable requires https://).
Resources
- references/overview.md - Event names, payload fields, delivery behavior
- references/setup.md - Creating a system webhook and choosing authentication
- references/verification.md - Header check in Node, Python and Next.js, gotchas
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests