Outgoing · Real-time Events

Webhooks

Receive real-time notifications when emails are sent, delivered, opened, clicked, bounced, or unsubscribed. Keep your systems in sync.

Overview

Markt sends webhooks as HTTP POST requests to your configured endpoint whenever an event occurs. Each webhook includes an HMAC-SHA256 signature for verification and is automatically retried up to 3 times if delivery fails.

HTTP POST

All webhooks are sent as POST requests with JSON payloads

HMAC-SHA256

Each webhook includes a signature header for verification

3 Retries

Automatic retry with exponential backoff on failure

Setup

Configure webhooks from your team settings in the dashboard. You can set up multiple webhook endpoints and choose which events each endpoint receives.

  • 1. Add your webhook URL in team settings
  • 2. Select which events to receive
  • 3. Copy your webhook secret for signature verification
  • 4. Test your endpoint with a test webhook
  • 5. Monitor delivery logs for failed attempts

Events

Markt sends webhooks for the following events:

Event Description
email.sent Email was successfully sent from Markt
email.delivered Email was delivered to recipient's mailbox
email.opened Recipient opened the email
email.clicked Recipient clicked a link in the email
email.bounced Email bounced (hard or soft bounce)
email.complained Recipient marked email as spam
email.unsubscribed Recipient unsubscribed from emails

Payload Format

All webhooks are sent as JSON objects with the following structure:

{
  "event": "email.sent",
  "timestamp": "2024-01-15T10:00:00Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "email": "[email protected]",
    ...
  }
}

Each webhook includes the following headers:

  • Content-Type: application/json
  • X-Markt-Signature: sha256=... — HMAC-SHA256 signature
  • X-Markt-Event: email.sent — Event type
  • X-Markt-Timestamp: 1705315200 — Unix timestamp

Event Details

email.sent

Triggered when an email is successfully sent from Markt to your email provider.

{
  "event": "email.sent",
  "timestamp": "2024-01-15T10:00:00Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]",
    "subject": "Welcome to Markt"
  }
}
email.delivered

Triggered when the email provider confirms delivery to the recipient's mailbox.

{
  "event": "email.delivered",
  "timestamp": "2024-01-15T10:00:05Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]"
  }
}
email.opened

Triggered when the recipient opens the email (tracking pixel loaded).

{
  "event": "email.opened",
  "timestamp": "2024-01-15T10:15:30Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]",
    "user_agent": "Mozilla/5.0..."
  }
}
email.clicked

Triggered when the recipient clicks a tracked link in the email.

{
  "event": "email.clicked",
  "timestamp": "2024-01-15T10:16:00Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]",
    "url": "https://example.com/product"
  }
}
email.bounced

Triggered when an email bounces (hard or soft bounce).

{
  "event": "email.bounced",
  "timestamp": "2024-01-15T10:00:10Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]",
    "bounce_type": "hard",
    "reason": "550 5.1.1 User unknown"
  }
}
email.complained

Triggered when the recipient marks the email as spam.

{
  "event": "email.complained",
  "timestamp": "2024-01-15T10:20:00Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "step_id": 1,
    "email": "[email protected]"
  }
}
email.unsubscribed

Triggered when the recipient clicks the unsubscribe link.

{
  "event": "email.unsubscribed",
  "timestamp": "2024-01-15T10:25:00Z",
  "data": {
    "contact_id": 123,
    "campaign_id": 45,
    "email": "[email protected]"
  }
}

Signature Verification

Each webhook includes an HMAC-SHA256 signature in the X-Markt-Signature header. Verify the signature to ensure the webhook came from Markt and hasn't been tampered with.

How it works:

The signature is computed as: HMAC-SHA256(webhook_secret, request_body + timestamp)

Node.js

const crypto = require('crypto');

function verifySignature(secret, signature, body, timestamp) {
  const payload = body + timestamp;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature.replace('sha256=', '')),
    Buffer.from(expected)
  );
}

PHP

function verifySignature($secret, $signature, $body, $timestamp) {
  $payload = $body . $timestamp;
  $expected = hash_hmac('sha256', $payload, $secret);
  return hash_equals(
    str_replace('sha256=', '', $signature),
    $expected
  );
}

Python

import hmac
import hashlib

def verify_signature(secret, signature, body, timestamp):
    payload = body + timestamp
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(
        signature.replace('sha256=', ''),
        expected
    )

Retry Policy

If a webhook delivery fails (non-2xx response or timeout), Markt will automatically retry the delivery:

Setting Value
Max Attempts 3
Backoff 30 seconds
Timeout 10 seconds
Success Response 2xx status code

Delivery Logs

Monitor webhook delivery from your team settings. Each delivery attempt is logged with:

  • - Timestamp of the attempt
  • - HTTP status code received
  • - Response body (if any)
  • - Error message (if failed)
  • - Retry attempt number

Need API access?

Use our REST API to manage contacts, control campaigns, and retrieve statistics programmatically.