Skip to main content
Subscribe to events from Hiveku’s email service so your app can react in real time — log deliveries, handle bounces, fire workflows when a lead opens an email, and more.

Add a Webhook

1

Open the Webhooks tab

In your project, go to Settings > Email Service > Webhooks.
2

Click Add Webhook

Click + Add Webhook to open the configuration form.
3

Enter the endpoint URL

Your webhook URL must be publicly reachable over HTTPS. Localhost and private IPs won’t work — use a tunnel like ngrok for local testing.
4

Select events

Pick the events you want. Choose specific events or * for everything:
  • delivery — message was accepted by the recipient’s mail server
  • bounce — message was rejected (hard or soft)
  • complaint — recipient marked the message as spam
  • open — recipient opened the email (tracking pixel)
  • click — recipient clicked a tracked link
  • * — all events
5

Optional: filter by tag

Narrow the webhook to emails tagged with specific labels — useful when different parts of your app need different event streams (e.g., a campaign webhook vs. a transactional webhook).
6

Save

Click Save. Hiveku generates a signing secret — copy it and store it as an env var for your webhook handler.

Webhook Payload

Each event POSTs JSON to your endpoint:
{
  "event_id": "evt_01J9Q2K8X3M4N5P6Q7R8S9T0",
  "event_type": "delivery",
  "timestamp": "2026-04-17T12:34:56Z",
  "email_id": "msg_01J9Q2K8X3M4N5P6Q7R8S9T1",
  "to": "customer@example.com",
  "from": "hello@yoursite.com",
  "subject": "Your receipt",
  "tags": ["transactional", "receipt"],
  "metadata": {
    "provider_message_id": "0100018f-abc...",
    "smtp_response": "250 2.0.0 OK"
  }
}
Different event types include additional fields — for click events, you’ll also get a url field with the clicked link.

Verify Signatures

Every request includes an X-Hiveku-Signature header with an HMAC-SHA256 of the raw request body. Verify it before trusting the payload.
import crypto from 'crypto';

function verifyWebhook(
  rawBody: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// In your webhook handler:
export default async function handler(req: Request) {
  const rawBody = await req.text();
  const signature = req.headers.get('x-hiveku-signature');

  if (!signature || !verifyWebhook(rawBody, signature, process.env.HIVEKU_WEBHOOK_SECRET!)) {
    return new Response('Invalid signature', { status: 401 });
  }

  const event = JSON.parse(rawBody);
  // handle event...

  return Response.json({ received: true });
}
Always verify against the raw request body, not the parsed JSON. Parsing and re-serializing changes whitespace and key order, which breaks the signature.

Retry & Reliability

Hiveku retries failed deliveries with exponential backoff when your endpoint returns a 5xx status or times out.
  • Retries continue for up to 24 hours
  • Backoff starts at 30 seconds, doubles each attempt
  • Hiveku stops retrying after a successful 2xx response
If your endpoint returns 4xx or 5xx repeatedly, the webhook auto-disables. You’ll see the disabled status in the dashboard — fix the endpoint and re-enable.
Because events can be retried, your handler should be idempotent. Use the event_id field as a deduplication key.

Monitor Webhook Health

The Webhooks tab shows per-webhook metrics:
  • Success rate (2xx responses)
  • Failure rate (4xx/5xx)
  • Average latency
  • Last successful delivery
  • Last failure and reason
Hover over any row to see recent delivery attempts and response bodies — handy for debugging.

Filter by Tag

When you send an email, you can attach tags (tags: ['campaign-q2', 'newsletter']). Webhooks configured with tag filters only fire for matching emails. Typical use:
  • One webhook for transactional emails (receipts, auth) → logs to your analytics DB
  • Another for campaigns → updates CRM engagement scores
  • Another for cold outreach → triggers follow-up workflows

Verify Your Webhook

1

Send a test email

Use the dashboard Send Test button or call the email API with a real recipient.
2

Watch your endpoint

Within a few seconds of delivery, your webhook should fire with a delivery event. Check logs to confirm you received and verified it.
See the email webhooks reference for the full event schema.

Troubleshooting

Your URL must be publicly accessible HTTPS. localhost, 127.0.0.1, and private IP ranges are blocked. Use ngrok, Cloudflare Tunnel, or deploy to a staging URL for local testing.
Use the raw request body, not the parsed JSON. Call req.text() and verify against that string, then parse separately. Middleware that auto-parses JSON before your handler will break verification.
Too many consecutive failures. Fix your endpoint (check logs for the error), then click Re-enable on the webhook row. Consider adding error-handling upstream so a single bug doesn’t take down your webhook.
Expected during retries if your handler’s first response was slow or ambiguous. De-duplicate using the event_id field — store processed IDs for 24 hours and skip duplicates.
Double-check the events you subscribed to. open and click events require email tracking to be enabled on the original send. Transactional emails often have tracking off by default.

What’s Next?

Send Emails

Start sending emails that fire webhook events

Email Webhooks Reference

Full event schema and API details