Email Tracking

Track the complete lifecycle of emails with UUIDs returned in SMTP responses and queryable activity logs.

SMTP Response UUID

When Mailhooks accepts an email via SMTP, the response includes a unique UUID that can be used to track the email through our system. This is useful for correlating support requests and debugging delivery issues.

250 Message accepted 87b1afa5-bdce-44c2-8a17-819cb2ac8afd

Example SMTP Session

220 mailhooks.dev ESMTP
HELO client.example.com
250 mailhooks.dev Nice to meet you, client.example.com
MAIL FROM:
250 Accepted
RCPT TO:
250 Accepted
DATA
354 End data with .
Subject: Test Email
From: [email protected]
To: [email protected]

Hello, this is a test email.
.
250 Message accepted 87b1afa5-bdce-44c2-8a17-819cb2ac8afd
QUIT
221 Bye

Email Lifecycle

Each email goes through several processing stages, all tracked with activity logs linked by the email UUID.

1
SMTP Received

Email accepted via SMTP, UUID returned

2
Spam Check

SPF, DKIM, DMARC verification

3
Webhook Delivery

POST to your webhook endpoints

4
Discord Notification

Optional Discord integration

Example Lifecycle Timeline
10:00:01
SMTP_RECEIVED
SUCCESSEmail received from [email protected]
10:00:02
SPAM_CHECK
SUCCESSAuth: pass (SPF: pass, DKIM: pass, DMARC: pass)
10:00:03
WEBHOOK
SUCCESSDelivered to https://api.example.com/hook

Unified Logs Endpoint

Query all activity logs across your account with powerful filtering options.

GET undefined/api/v1/logs

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
perPageintegerItems per page (default: 50, max: 100)
typestringFilter by log type (SMTP_RECEIVED, SPAM_CHECK, WEBHOOK, DISCORD, DISCORD_BOT)
statusstringFilter by status (SUCCESS, FAILED, PENDING)
emailIdstringFilter by email UUID
environmentIdstringFilter by environment ID

Example Request

# Get all failed webhook deliveries
curl -H "x-api-key: mh_your_api_key_here" \
     "undefined/api/v1/logs?type=WEBHOOK&status=FAILED"

Querying Logs by Email

Use the email UUID to retrieve all activity logs for a specific email.

GET undefined/api/v1/logs/email/:emailId

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
perPageintegerItems per page (default: 50)

Response

{
  "data": [
    {
      "id": "log_abc123",
      "type": "SMTP_RECEIVED",
      "status": "SUCCESS",
      "message": "Email received from [email protected]",
      "metadata": {
        "baseEmailId": "87b1afa5-bdce-44c2-8a17-819cb2ac8afd",
        "from": "[email protected]",
        "to": ["[email protected]"],
        "subject": "Test Email",
        "remoteAddress": "192.168.1.100",
        "size": 1024
      },
      "createdAt": "2024-01-15T10:00:01Z"
    },
    {
      "id": "log_def456",
      "type": "SPAM_CHECK",
      "status": "SUCCESS",
      "message": "Auth: pass (SPF: pass, DKIM: pass, DMARC: pass)",
      "metadata": {
        "spfResult": "pass",
        "dkimResult": "pass",
        "dmarcResult": "pass",
        "authSummary": "pass"
      },
      "createdAt": "2024-01-15T10:00:02Z"
    },
    {
      "id": "log_ghi789",
      "type": "WEBHOOK",
      "status": "SUCCESS",
      "message": "Successfully delivered webhook wh_123 for email",
      "metadata": {
        "webhookId": "wh_123",
        "statusCode": 200,
        "durationMs": 150
      },
      "createdAt": "2024-01-15T10:00:03Z"
    }
  ],
  "currentPage": 1,
  "perPage": 50,
  "totalItems": 3,
  "totalPages": 1,
  "hasNextPage": false
}

Resend Notification

Retry a failed webhook or Discord notification by resending it from a specific log entry.

POST undefined/api/v1/logs/:logId/resend

Example Request

curl -X POST "undefined/api/v1/logs/log_ghi789/resend" \
     -H "x-api-key: mh_your_api_key_here"

Response

{
  "success": true,
  "message": "Notification resent successfully",
  "newLogId": "log_xyz123"
}

Log Types

The following log types are tracked for each email:

TypeDescriptionMetadata
SMTP_RECEIVEDEmail received via SMTPfrom, to, subject, remoteAddress, size
SPAM_CHECKSPF/DKIM/DMARC verificationspfResult, dkimResult, dmarcResult, authSummary
WEBHOOKWebhook delivery attemptwebhookId, statusCode, durationMs, attemptsMade
DISCORDDiscord webhook notificationintegrationId, attemptsMade
DISCORD_BOTDiscord bot notificationchannelConfigId, channelId, guildId

Code Examples

cURL

curl -X GET "undefined/api/v1/logs/email/87b1afa5-bdce-44c2-8a17-819cb2ac8afd" \
     -H "x-api-key: mh_your_api_key_here"

JavaScript/Node.js

const emailId = '87b1afa5-bdce-44c2-8a17-819cb2ac8afd';

const response = await fetch(
  `undefined/api/v1/logs/email/${emailId}`,
  {
    headers: {
      'x-api-key': process.env.MAILHOOKS_API_KEY
    }
  }
);

const { data: logs } = await response.json();

// Show the email lifecycle
logs.forEach(log => {
  console.log(`[${log.createdAt}] ${log.type}: ${log.status} - ${log.message}`);
});

Python

import requests
import os

email_id = '87b1afa5-bdce-44c2-8a17-819cb2ac8afd'

response = requests.get(
    f'undefined/api/v1/logs/email/{email_id}',
    headers={'x-api-key': os.environ['MAILHOOKS_API_KEY']}
)

logs = response.json()['data']

# Show the email lifecycle
for log in logs:
    print(f"[{log['createdAt']}] {log['type']}: {log['status']} - {log['message']}")