Chat bot builder? Go to buzzmark.chat

Developers

Webhooks

A signed POST to your endpoint whenever something happens to a message - delivered, bounced, marked as spam, opened or clicked - plus inbound mail as JSON.

Setting up

The request

Example request HTTP
POST /webhooks/buzzmark HTTP/1.1
Host: your-app.com
Content-Type: application/json
X-Buzzmark-Event: delivery
X-Buzzmark-Signature: 5d41402abc4b2a76b9719d911017c592...

{
  "RecordType": "Delivery",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "customer@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-24T10:15:06+00:00"
}

Verifying signatures

PHP Laravel
// Laravel: verify before trusting the payload
$signature = (string) $request->header('X-Buzzmark-Signature');
$expected = hash_hmac('sha256', $request->getContent(), $webhookSecret);

if (! hash_equals($expected, $signature)) {
    abort(401);
}

$event = $request->json()->all();
Node.js Express
// Express: keep the raw body for the signature
app.post('/webhooks/buzzmark', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto
    .createHmac('sha256', process.env.BUZZMARK_WEBHOOK_SECRET)
    .update(req.body)
    .digest('hex');
  const given = req.get('X-Buzzmark-Signature') || '';

  if (given.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected))) {
    return res.sendStatus(401);
  }

  const event = JSON.parse(req.body);
  res.sendStatus(200);
});
Python Flask
# Flask
import hashlib, hmac

@app.post("/webhooks/buzzmark")
def buzzmark_webhook():
    expected = hmac.new(SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, request.headers.get("X-Buzzmark-Signature", "")):
        abort(401)
    event = request.get_json()
    return "", 200

Responses & retries

Events

delivery

POST your webhook URL · X-Buzzmark-Event: delivery

Auth: X-Buzzmark-Signature

Payload JSON
{
  "RecordType": "Delivery",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "customer@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-24T10:15:06+00:00"
}

bounce

POST your webhook URL · X-Buzzmark-Event: bounce

Auth: X-Buzzmark-Signature

Payload JSON
{
  "RecordType": "Bounce",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "gone@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-24T10:15:09+00:00",
  "Type": "HardBounce",
  "Description": "550 5.1.1 The email account that you tried to reach does not exist"
}

spam_complaint

POST your webhook URL · X-Buzzmark-Event: spam_complaint

Auth: X-Buzzmark-Signature

Payload JSON
{
  "RecordType": "SpamComplaint",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "customer@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-25T08:02:41+00:00"
}

open

POST your webhook URL · X-Buzzmark-Event: open

Auth: X-Buzzmark-Signature

Payload JSON
{
  "RecordType": "Open",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "customer@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-24T10:21:40+00:00"
}

click

POST your webhook URL · X-Buzzmark-Event: click

Auth: X-Buzzmark-Signature

Payload JSON
{
  "RecordType": "Click",
  "MessageID": "f5ab446c-18ad-4db4-b747-8e1ba70ec72d",
  "Recipient": "customer@example.com",
  "Tag": "receipt",
  "Metadata": { "order_id": "1234" },
  "ReceivedAt": "2026-10-24T10:22:03+00:00",
  "OriginalLink": "https://acme.com/orders/1234"
}

Inbound mail

Inbound mail

POST the hive's inbound webhook URL

Auth: X-Buzzmark-Inbound-Hash

Payload JSON
{
  "RecordType": "Inbound",
  "MessageID": "9d1e7c3a-2b4f-4c1a-8e0d-5f6a7b8c9d0e",
  "From": "Maria Lopez <maria@cliente.es>",
  "FromName": null,
  "To": "support@acme.com",
  "OriginalRecipient": "support@acme.com",
  "Subject": "Where is my order?",
  "HtmlBody": "<p>Hi, order 1234 hasn't arrived yet.</p>",
  "TextBody": "Hi, order 1234 hasn't arrived yet.",
  "Headers": [{ "Name": "X-Mailer", "Value": "Apple Mail" }],
  "Attachments": [
    { "Name": "photo.jpg", "ContentType": "image/jpeg", "ContentLength": 48213 }
  ],
  "ReceivedAt": "2026-10-24T11:04:17+00:00"
}