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-819cb2ac8afdExample 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.
Email accepted via SMTP, UUID returned
SPF, DKIM, DMARC verification
POST to your webhook endpoints
Optional Discord integration
Unified Logs Endpoint
Query all activity logs across your account with powerful filtering options.
GET undefined/api/v1/logsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
perPage | integer | Items per page (default: 50, max: 100) |
type | string | Filter by log type (SMTP_RECEIVED, SPAM_CHECK, WEBHOOK, DISCORD, DISCORD_BOT) |
status | string | Filter by status (SUCCESS, FAILED, PENDING) |
emailId | string | Filter by email UUID |
environmentId | string | Filter 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/:emailIdQuery Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
perPage | integer | Items 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/resendExample 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:
| Type | Description | Metadata |
|---|---|---|
SMTP_RECEIVED | Email received via SMTP | from, to, subject, remoteAddress, size |
SPAM_CHECK | SPF/DKIM/DMARC verification | spfResult, dkimResult, dmarcResult, authSummary |
WEBHOOK | Webhook delivery attempt | webhookId, statusCode, durationMs, attemptsMade |
DISCORD | Discord webhook notification | integrationId, attemptsMade |
DISCORD_BOT | Discord bot notification | channelConfigId, 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']}")