API Docs

Webhooks

Receive email events in real time.

Overview

When you set up webhooks, an HTTP POST request is sent to the specified URL whenever events such as email sending, opens, or clicks occur.

Webhooks can be configured in Dashboard > Webhooks.

Event Types

Event Description
email.sent When an email is sent
email.delivered When an email is delivered to the recipient
email.opened When a recipient opens an email
email.clicked When a recipient clicks a link in an email
email.bounced When an email bounces
email.complained When a recipient reports the email as spam
subscriber.created When a new subscriber is added
subscriber.unsubscribed When a subscriber unsubscribes
campaign.sent When a campaign sending starts
campaign.completed When a campaign sending is completed

Payload Format

All webhook requests include a JSON payload in the following format:

{
  "event": "email.opened",
  "timestamp": "2026-01-10T12:00:00+00:00",
  "data": {
    "campaign_id": 123,
    "campaign_uuid": "abc-123...",
    "campaign_name": "January Newsletter",
    "subscriber_id": 456,
    "subscriber_uuid": "def-456...",
    "subscriber_email": "user@example.com",
    "ip_address": "1.2.3.4",
    "user_agent": "Mozilla/5.0...",
    "occurred_at": "2026-01-10T12:00:00+00:00"
  }
}

Request Headers

Header Description
Content-Type application/json
X-Webhook-ID Webhook UUID
X-Webhook-Event Event type (e.g. email.opened)
X-Webhook-Signature HMAC-SHA256 signature

Signature Verification

Verify the X-Webhook-Signature header to confirm the authenticity of webhook requests. The signature is an HMAC-SHA256 hash using the webhook secret and the request body.

PHP Example

<?php
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$secret = 'your_webhook_secret';

$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    die('Invalid signature');
}

$data = json_decode($payload, true);
// Process the event...

Node.js Example

const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

// Express.js example
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const payload = JSON.stringify(req.body);

  if (!verifySignature(payload, signature, 'your_secret')) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event...
  res.status(200).send('OK');
});

Retry Policy

  • • If a webhook delivery fails (non-2xx response), it will not be automatically retried.
  • • After 5 consecutive failures, the webhook is automatically deactivated.
  • • Deactivated webhooks can be re-enabled from the dashboard.
  • • Response time must be within 10 seconds.

Best Practices

  • • Always verify the signature to confirm the authenticity of requests.
  • • Process webhooks as quickly as possible (within 5 seconds).
  • • Queue long-running tasks and return 200 OK immediately.
  • • Use HTTPS endpoints to transmit data securely.

We use cookies

We use cookies to improve your experience. You can choose which cookie categories to allow. Learn more