Skip to main content
GET
/
public
/
v1
/
emails
/
{id}
/
stats
Retrieve one-shot email statistics
curl --request GET \
  --url https://api.minimo.it/public/v1/emails/{id}/stats \
  --header 'Authorization: Bearer <token>'
{
  "data": {
    "id": "DMPNEF8",
    "status": "sent",
    "to": "customer@example.com",
    "subject": "Your receipt",
    "sentAt": "2026-05-19T10:30:00Z",
    "opened": false,
    "firstOpenAt": null,
    "clickCount": 0,
    "firstClickAt": null,
    "failureReason": null
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.minimo.it/llms.txt

Use this file to discover all available pages before exploring further.

Overview

After dispatching an email through POST /public/v1/emails, use the returned id (or the full statsUrl) to read back delivery and engagement metrics for that single delivery. Unlike the template-stats endpoint, these numbers refer to one recipient and one HTML payload — not aggregated counters across a campaign.
The endpoint is scoped to your company. IDs that belong to a different company return 404, never another tenant’s data.

Request

curl --request GET \
  --url https://api.minimo.it/public/v1/emails/DMPNEF8/stats \
  --header 'Authorization: Bearer mn-{apiClientId}-{secret}'

Response Example

{
  "data": {
    "id": "DMPNEF8",
    "status": "sent",
    "to": "customer@example.com",
    "subject": "Your receipt",
    "sentAt": "2026-05-19T10:30:00Z",
    "opened": true,
    "firstOpenAt": "2026-05-19T10:32:14Z",
    "clickCount": 2,
    "firstClickAt": "2026-05-19T10:33:05Z",
    "failureReason": null
  }
}

Field Reference

FieldTypeDescription
idstringEcho of the opaque sqid id returned by the POST endpoint.
status"pending" | "sent" | "failed"Lifecycle state of the delivery.
tostringRecipient address as it was sent.
subjectstringSubject line as it was sent.
sentAtdate-timeWhen the delivery row was created (queue-in time, not provider acceptance).
openedbooleantrue once the tracking pixel has been fetched at least once.
firstOpenAtdate-time | nullTimestamp of the first open; null until the pixel is fetched.
clickCountintegerTotal number of clicks across all tracked links in the email.
firstClickAtdate-time | nullTimestamp of the earliest tracked click; null until the first click.
failureReasonstring | nullPopulated when status = "failed" — the provider’s rejection reason.

How the Counters Are Updated

  • Open: triggered the first time the recipient’s email client fetches the embedded <img> open-pixel. Image proxies (Gmail, Apple Mail Privacy Protection) trigger this immediately on arrival, which inflates open rates compared to pre-2021 baselines.
  • Click: every fetch of a rewritten /api/click/... URL appends a row to the click ledger. clickCount is the cardinality of that ledger; firstClickAt is its minimum timestamp.
Both signals are per delivery: opens and clicks tied to a different id do not affect this row.

Use Cases

When status === "failed", persist failureReason against the originating business object so support can react.
const { data: stats } = await getEmailStats(id);
if (stats.status === 'failed') {
  await logDeliveryFailure({ id, reason: stats.failureReason });
}
The first click timestamp lets you measure end-to-end latency from “we sent it” to “user acted.”
const { data: stats } = await getEmailStats(id);
if (stats.firstClickAt) {
  const sentAt = new Date(stats.sentAt);
  const clickedAt = new Date(stats.firstClickAt);
  const minutesToFirstClick = (clickedAt - sentAt) / 60000;
  track('email_click_latency_minutes', minutesToFirstClick);
}

Common Errors

StatusCause
401API key missing or malformed.
403API key lacks the TRANSACTIONAL permission.
404The id doesn’t exist, or it belongs to a different company than the one this API key authorizes.

Polling Guidance

  • Open events: usually surface within seconds for image-proxied clients (Gmail, Apple Mail Privacy Protection). For other clients, wait until the recipient actually opens the message.
  • Click events: stored synchronously the moment the rewritten URL is fetched — they appear in the next stats response.
  • Rate: a steady cadence of one poll every 30–60 seconds for the first ~10 minutes is plenty. Aggressive polling won’t surface data faster.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

id
string
required

Opaque sqid id returned by POST /public/v1/emails.

Example:

"DMPNEF8"

Response

Statistics for the delivery.

data
object