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/jsonX-Markt-Signature: sha256=...— HMAC-SHA256 signatureX-Markt-Event: email.sent— Event typeX-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.