Enlist POSTs a signed JSON body to your endpoint for five event types — new signups, removals, and signup-email delivered/opened/clicked.
import { createHmac, timingSafeEqual } from 'node:crypto';function verify(secret: string, timestamp: string, body: string, signature: string) { const expected = createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex'); const provided = signature.replace(/^v1=/, ''); return timingSafeEqual(Buffer.from(expected), Buffer.from(provided));}export async function POST(request: Request) { const body = await request.text(); const timestamp = request.headers.get('enlist-timestamp')!; const signature = request.headers.get('enlist-signature')!; if (!verify(process.env.ENLIST_WEBHOOK_SECRET!, timestamp, body, signature)) { return new Response('Invalid signature', { status: 401 }); } const event = JSON.parse(body); // event.type: 'signup.created' | 'signup.email_delivered' | … // event.data: { id, waitlist_id, email, position, … } return new Response('ok');}signup.created, signup.removed, signup.email_delivered, signup.email_opened, signup.email_clicked — filter to only what you subscribe to.
Every request carries enlist-timestamp and enlist-signature (HMAC-SHA256). Reject anything older than a few minutes.
No automatic retries — treat a missed event as possible and reconcile against the API rather than assuming every event arrives.
REST, SDK, MCP, webhooks, and email — same key across all of them.