MailLandDocs

Analytics Overview

Track email performance with real-time event summaries, daily stats, rates, and volume metrics

MailLand provides real-time analytics powered by ClickHouse for high-performance aggregation across millions of events. Track deliveries, opens, clicks, bounces, and complaints with flexible date ranges and email type filtering.

Event Summary

Get aggregate event counts for a period:

GET https://api.mail.land/v1/transactional/analytics/events/summary
Get event summary
curl "https://api.mail.land/v1/transactional/analytics/events/summary?from=2026-01-18&to=2026-02-17" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

Query Parameters

ParameterTypeDefaultDescription
fromdatetime30 days agoStart date (alias: startDate)
todatetimeNowEnd date (alias: endDate)
emailTypeint-0 = Transactional, 1 = Marketing, omit for all
refreshboolfalseBypass cache and fetch fresh data
Event summary response
{
  "from": "2026-01-18T00:00:00Z",
  "to": "2026-02-17T23:59:59Z",
  "sent": 142500,
  "delivered": 140325,
  "opened": 44878,
  "clicked": 5843,
  "bounced": 1125,
  "complained": 28,
  "source": "clickhouse",
  "data_source": "clickhouse",
  "is_degraded": false,
  "queryTimeMs": 45
}
FieldDescription
sentEmails accepted by the MTA
deliveredSuccessfully delivered to recipient's mail server
openedUnique messages with at least one open event: includes machine activity (see callout below)
clickedUnique messages with at least one click event: includes machine activity (see callout below)
bouncedPermanent failures: hard bounces, expired messages (retries exhausted), and admin bounces. Out-of-band bounces are not currently counted (known gap, tracked separately)
complainedRecipients who filed spam complaints
sourceData source: clickhouse, postgres (fallback) or cache
data_source, fallback_reason, is_degradedsnake_case fields describing degraded/fallback state: only the event summary endpoint falls back to PostgreSQL, and it is marked is_degraded: true when it does; other analytics endpoints are ClickHouse-only
queryTimeMsQuery execution time in milliseconds

Opens and clicks include machine activity, Apple Mail Privacy Protection prefetch and security link scanners, which MailLand does not filter today. Treat these figures as an upper bound on human engagement, not a precise count.

The response includes X-Cache: HIT, MISS, or FRESH headers indicating whether data was served from cache. Use refresh=true to force a fresh query.

Daily Stats

Get per-day event breakdowns for charting:

GET https://api.mail.land/v1/transactional/analytics/stats/daily
Get daily stats
curl "https://api.mail.land/v1/transactional/analytics/stats/daily?from=2026-01-18&to=2026-02-17" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
ParameterTypeDefaultDescription
fromdatetimethe last 7 whole UTC daysStart date
todatetimeNowEnd date
emailTypeint-Filter by email type
Daily stats response
[
  {
    "date": "2026-02-17T00:00:00Z",
    "sent": 4750,
    "delivered": 4680,
    "opened": 1498,
    "clicked": 195,
    "bounced": 38
  },
  {
    "date": "2026-02-16T00:00:00Z",
    "sent": 4320,
    "delivered": 4260,
    "opened": 1380,
    "clicked": 175,
    "bounced": 32
  }
]

Rates

Get delivery, open, and click rates calculated as percentages:

GET https://api.mail.land/v1/transactional/analytics/rates
Get rates
curl "https://api.mail.land/v1/transactional/analytics/rates?from=2026-01-18&to=2026-02-17" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
ParameterTypeDefaultDescription
fromdatetime30 days agoStart date
todatetimeNowEnd date
emailTypeint-Filter by email type
Rates response
{
  "from": "2026-01-18T00:00:00Z",
  "to": "2026-02-17T23:59:59Z",
  "deliveryRate": 98.47,
  "openRate": 31.49,
  "clickRate": 13.02
}

Rate calculations:

RateFormula
Delivery ratedelivered / accepted * 100 (capped at 100): not sent
Open rateopened / delivered * 100 (capped at 100)
Click rateclicked / delivered * 100 (capped at 100): not clicked / opened

All three rate queries execute in parallel for optimal performance.

See the most clicked links across your emails:

GET https://api.mail.land/v1/transactional/analytics/links/top
Get top links
curl "https://api.mail.land/v1/transactional/analytics/links/top?from=2026-01-18&to=2026-02-17&limit=10" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
ParameterTypeDefaultDescription
fromdatetime30 days agoStart date
todatetimeNowEnd date
limitint10Max links to return
emailTypeint-Filter by email type
Top links response
[
  {
    "url": "https://your-app.com/orders/track",
    "clicks": 2340,
    "uniqueRecipients": 1890
  },
  {
    "url": "https://your-app.com/dashboard",
    "clicks": 1150,
    "uniqueRecipients": 980
  }
]

Hourly Volume

Track sending volume by hour, with optional baseline overlay for anomaly detection:

GET https://api.mail.land/v1/transactional/analytics/volume/hourly?days=7
Get hourly volume
curl "https://api.mail.land/v1/transactional/analytics/volume/hourly?days=7" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
ParameterTypeDefaultDescription
daysint7Lookback period (1–30)
Hourly volume response
[
  {
    "hour": "2026-02-17T14:00:00Z",
    "sent": 520,
    "baseline": 480.5
  },
  {
    "hour": "2026-02-17T13:00:00Z",
    "sent": 495,
    "baseline": 480.5
  }
]

The baseline is the historical average volume for that hour of day, computed by the VolumeAnomalyWorker. It's null if no baseline data is available yet.

Caching

Analytics endpoints are cached server-side to minimize query load:

EndpointCache TTL
events/summary (default range)5 minutes
events/summary (custom range)3 minutes
stats/daily3 minutes
rates3 minutes
links/top5 minutes
volume/hourly3 minutes

The events/summary endpoint coalesces concurrent identical requests per server: only one query hits ClickHouse per API instance, and all callers on that instance receive the same result. The other endpoints on this page do not coalesce; each request reads the cache and then queries.

Data Sources

MailLand uses ClickHouse as the primary analytics data source for fast aggregation over billions of events.

Only events/summary falls back to PostgreSQL when ClickHouse is unavailable or returns no data, and that response is marked is_degraded: true when it does. Every other analytics endpoint on this page is ClickHouse-only and has no fallback.

The source field in responses indicates which data store served the result. The queryTimeMs field helps monitor performance.

Retention

Analytics event data follows the workspace's plan: logs are kept 30 days on Free, 90 days on Pro, and 180 days on Max.

Next Steps

On this page