MailLandDocs

Email Logs

Search, filter, and inspect detailed delivery logs for every email sent through Mail.Land

This page lists transactional messages only: campaign and automation mail (sys_* system messages included) are excluded. Use the campaign recipients endpoint (see Campaigns) for marketing/automation send history.

List Emails

GET https://api.mail.land/v1/transactional/logs
List emails
curl "https://api.mail.land/v1/transactional/logs?limit=20" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Query Parameters

ParameterTypeDefaultDescription
cursorstring-Opaque cursor from the previous page's nextCursor. Omit for the first page. A malformed or tampered cursor returns 400 INVALID_CURSOR.
limitint20Items per page
statusstring-Filter by status (see below)
searchstring-Search recipient, subject, or message ID
fromdatetime30 days agoStart date
todatetimeNowEnd date
refreshboolfalseAvoid a stale page: there is no longer a count cache to bypass

Status Filters

ValueMatches
queuedWaiting in queue
sentAccepted by MTA
deferred or retryingTemporarily delayed
deliveredSuccessfully delivered
bouncedHard bounce
failedSystem error or admin bounce
openedRecipient opened the email
clickedRecipient clicked a link
complainedRecipient filed spam complaint
Email logs response
{
  "items": [
    {
      "messageId": "t_a1b2c3d4e5f6",
      "recipient": "[email protected]",
      "subject": "Your order has shipped",
      "status": "delivered",
      "sentAt": "2026-02-17T12:34:56Z",
      "deliveredAt": "2026-02-17T12:34:58Z",
      "openedAt": "2026-02-17T13:15:00Z",
      "clickedAt": null,
      "bounceReason": null,
      "openCount": 2,
      "clickCount": 0
    },
    {
      "messageId": "t_d4e5f6a1b2c3",
      "recipient": "[email protected]",
      "subject": "Invoice #1234",
      "status": "bounced",
      "sentAt": "2026-02-17T12:30:00Z",
      "deliveredAt": null,
      "openedAt": null,
      "clickedAt": null,
      "bounceReason": "550 5.1.1 Mailbox not found",
      "openCount": 0,
      "clickCount": 0
    }
  ],
  "nextCursor": "eyJ2IjoxLCJzIjoiY3JlYXRlZGF0OmRlc2MiLCJrIjoi...",
  "hasMore": true
}

Status Priority

The status field reflects the highest-priority event for each email:

  1. complained (highest)
  2. clicked
  3. opened
  4. Delivery status: queued → sent → deferred → delivered → bounced → failed

For example, if an email was delivered and then opened, the status shows opened.

A default 30-day date range is applied for performance. The search parameter filters by recipient email, subject line, or message ID (case-insensitive).

Log Stats

Get aggregate statistics for your email logs:

GET https://api.mail.land/v1/transactional/logs/stats
Get log stats
curl "https://api.mail.land/v1/transactional/logs/stats" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
ParameterTypeDefaultDescription
fromdatetime7 days agoStart date
todatetimeNowEnd date
emailTypeint-0 = Transactional, 1 = Marketing. Omit to cover all email types: unlike List Emails above, which is transactional-only.
refreshboolfalseBypass cache
Log stats response
{
  "total": 4750,
  "accepted": 4750,
  "sent": 4700,
  "delivered": 4680,
  "opened": 1498,
  "clicked": 195,
  "bounced": 38,
  "complained": 1,
  "failed": 12,
  "queued": 20,
  "deliveryRate": 99.57,
  "openRate": 32.01,
  "clickRate": 13.02,
  "bounceRate": 0.81,
  "complaintRate": 0.021,
  "source": "clickhouse",
  "queryTimeMs": 32
}

Rate calculations:

RateFormula
deliveryRatedelivered / sent * 100
openRateopened / delivered * 100
clickRateclicked / delivered * 100
bounceRatebounced / sent * 100
complaintRatecomplained / sent * 100 (3 decimal places)

Response headers indicate cache status:

HeaderValues
X-CacheHIT, MISS, or FRESH
X-Stats-Sourcecache or clickhouse
Cache-ControlAlways no-store, no-cache, must-revalidate

Email Detail

Get full details for a specific email, including the event timeline:

GET https://api.mail.land/v1/transactional/logs/{messageId}
Get email detail
curl https://api.mail.land/v1/transactional/logs/t_a1b2c3d4e5f6 \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
Email detail response
{
  "messageId": "t_a1b2c3d4e5f6",
  "recipient": "[email protected]",
  "fromEmail": "[email protected]",
  "subject": "Your order has shipped",
  "status": "opened",
  "sentAt": "2026-02-17T12:34:56Z",
  "deliveredAt": "2026-02-17T12:34:58Z",
  "openedAt": "2026-02-17T13:15:00Z",
  "clickedAt": null,
  "createdAt": "2026-02-17T12:34:55Z",
  "bounceReason": null,
  "bounceCategory": null,
  "ipAddress": null,
  "retryCount": 0,
  "smtpResponse": "250 2.0.0 OK",
  "openCount": 2,
  "clickCount": 0,
  "htmlContent": "<html>...</html>",
  "textContent": "Your order has shipped...",
  "events": [
    {
      "eventType": "delivered",
      "timestamp": "2026-02-17T12:34:58Z",
      "ipAddress": null,
      "userAgent": null,
      "linkUrl": null,
      "bounceType": null,
      "bounceReason": null,
      "smtpResponse": "250 2.0.0 OK",
      "deviceType": null,
      "browser": null,
      "country": null,
      "city": null
    },
    {
      "eventType": "opened",
      "timestamp": "2026-02-17T13:15:00Z",
      "ipAddress": "203.0.113.45",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
      "linkUrl": null,
      "bounceType": null,
      "bounceReason": null,
      "smtpResponse": null,
      "deviceType": "desktop",
      "browser": "Chrome",
      "country": "US",
      "city": "San Francisco"
    },
    {
      "eventType": "opened",
      "timestamp": "2026-02-17T14:30:00Z",
      "ipAddress": "203.0.113.45",
      "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)",
      "linkUrl": null,
      "bounceType": null,
      "bounceReason": null,
      "smtpResponse": null,
      "deviceType": "mobile",
      "browser": "Safari",
      "country": "US",
      "city": "San Francisco"
    }
  ]
}

The events array is sourced from ClickHouse and ordered by timestamp. If ClickHouse is temporarily unavailable, the email detail is still returned from PostgreSQL but events will be an empty array.

Event Fields

FieldDescription
eventTypedelivered, opened, clicked, bounced, complained, and also accepted, sent, deferred, admin_bounce, oob_bounce, expired
timestampWhen the event occurred (UTC)
ipAddressClient IP (for opens/clicks)
userAgentClient user agent string
linkUrlClicked URL (for clicked events)
bounceTypehard, soft, or unknown (for bounced events)
bounceReasonSMTP response (for bounced events)
smtpResponseRemote server response (for delivered events)
deviceTypedesktop, mobile, or tablet
browserBrowser name (Chrome, Safari, Firefox, etc.)
countryISO country code
cityCity name

Retry a Failed Email

Retry delivery of a bounced or failed email:

POST https://api.mail.land/v1/transactional/logs/{messageId}/retry
Retry failed email
curl -X POST https://api.mail.land/v1/transactional/logs/t_a1b2c3d4e5f6/retry \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

The message must be in Bounced or Failed status, and the recipient must not be suppressed.

StatusCodeDescription
200-Retry accepted
400INVALID_REQUESTEmail is not bounced or failed
400RECIPIENT_SUPPRESSEDRecipient is on the suppression list
404RESOURCE_NOT_FOUNDMessage not found: not EMAIL_NOT_FOUND
422DOMAIN_NOT_VERIFIEDThe sending domain is no longer verified
429MARKETING_PAUSEDMarketing sending is currently paused for this workspace
422RETRY_ATTACHMENTS_UNAVAILABLEThe message had attachments that can no longer be recovered; send it again with its attachments instead
422RETRY_ATTACHMENTS_UNKNOWNThe message was sent before attachments were recorded, so a retry cannot guarantee them; send it again instead
429PLATFORM_CAPACITY_PROTECTIONNew sending is briefly paused to protect platform capacity; nothing was changed, retry shortly
503RETRY_ATTACHMENT_STORAGE_UNAVAILABLEThe attachments could not be read right now; nothing was changed, retry shortly

The retry creates a new email job with the original content and queues it for delivery. Retried copies are sent without open/click tracking.

Next Steps

On this page