Webhooks API

Configure webhooks to receive real-time notifications when emails arrive.

How Webhooks Work

When an email is received, Mailhooks will send a POST request to your configured webhook URL with the email data. This allows you to process emails in real-time without polling the API.

1. Email Received

Email arrives at your domain

2. Webhook Triggered

POST request sent to your URL

3. Process Email

Your app handles the data

Create Webhook

Create a new webhook endpoint.

POST undefined/api/v1/webhooks

Request Body

{
  "url": "https://your-app.com/webhook/mailhooks",
  "events": ["email.received"],
  "description": "Production webhook for email processing"
}

Example Request

curl -X POST undefined/api/v1/webhooks \
     -H "x-api-key: mh_your_api_key_here" \
     -H "Content-Type: application/json" \
     -d '{
       "url": "https://your-app.com/webhook/mailhooks",
       "events": ["email.received"]
     }'

Webhook Endpoints

List Webhooks

Get all configured webhooks for your account.

GET undefined/api/v1/webhooks

Update Webhook

Update an existing webhook configuration.

PUT undefined/api/v1/webhooks/:id

Delete Webhook

Remove a webhook endpoint.

DELETE undefined/api/v1/webhooks/:id

Webhook Payload

When an email is received, Mailhooks sends the following payload to your webhook. If you use custom storage (BYOB), additional fields like storagePath are included so you can fetch the email and attachments from your bucket.

{
  "id": "em_1234567890",
  "from": "[email protected]",
  "to": ["[email protected]"],
  "subject": "Hello from Mailhooks",
  "body": "Plain text content of the email...",
  "html": "HTML content...

Payload Fields

FieldTypeDescription
idstringUnique email ID
fromstringSender email address
tostring[]Recipient email addresses
subjectstringEmail subject line
bodystringPlain text content
htmlstring?HTML content (if available)
receivedAtstringISO 8601 timestamp when email was received
headersobjectAll email headers as key-value pairs
attachmentsarrayList of attachments with id, filename, contentType, size, and storagePath (for custom storage)
spfResultstring?SPF authentication result
dkimResultstring?DKIM authentication result
dmarcResultstring?DMARC authentication result
authSummarystring?Summary of all authentication results
usesCustomStoragebooleanWhether email is stored in your custom S3 bucket (BYOB)
storagePathstring?Storage path for the EML file (only present when usesCustomStorage is true)
storageConfigobject?Storage provider details with provider (S3, AZURE_BLOB, GCS) and bucket name (only present when usesCustomStorage is true)

HTTP Headers

Mailhooks includes the following headers with each webhook request:

HeaderDescription
Content-Typeapplication/json
X-Webhook-SignatureHMAC-SHA256 signature of the payload
X-Email-IDThe email ID for reference

Webhook Security

Mailhooks signs all webhook requests to verify they're coming from us. The signature is included in the X-Webhook-Signature header.

Verifying Webhook Signatures

// Node.js example
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const hash = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  return hash === signature;
}

// In your webhook handler
app.post('/webhook/mailhooks', (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const isValid = verifyWebhookSignature(
    req.body,
    signature,
    process.env.MAILHOOKS_WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process the webhook...
});

Retry Policy

If your webhook endpoint doesn't respond with a 2xx status code, Mailhooks will retry the delivery with exponential backoff:

Retry 1

5 seconds

Retry 2

30 seconds

Retry 3

2 minutes

Retry 4

10 minutes

Retry 5

30 minutes

Webhook Logs

View logs for a specific webhook to debug delivery issues. Each log entry includes the emailId for correlation with the original email.

Use the email ID to track the complete email lifecycle including SMTP reception and spam checks. See the Email Tracking documentation for details.

GET undefined/api/v1/webhooks/:id/logs

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
perPageintegerItems per page (default: 20)
statusstringFilter by status: success, failed

Best Practices

Respond Quickly

Process webhooks asynchronously and return 200 OK immediately

Verify Signatures

Always validate webhook signatures before processing

Handle Duplicates

Use email IDs to prevent processing the same email twice

Monitor Health

Check webhook logs regularly for failed deliveries