Skip to content
Pidgely Docs

API reference · Metrics

Retrieve metrics

GEThttps://api.pidgely.com/metrics
View as Markdown

Sent, delivered, bounces, complaints, opens, clicks and their rates over a range of UTC days, by day or broken down by domain, tag, template, broadcast or mailbox provider. Read from rollups the event pipeline keeps up to date, so the cost is the same for ten emails or ten million. See Metrics for every definition.

Pidgely extension. Counters and rates over a UTC day range (default the last 30 days, at most 400), read from rollups the event pipeline keeps up to date. group_by=day (default) returns one point per day; domain, tag, template, broadcast (alias campaign) and provider (recipient mailbox provider: gmail, outlook, yahoo, icloud, other) return one point per value, most sent first. One filter (domain_id, tag, template_id, broadcast_id or provider) narrows the result to that value, by day. Rates: delivery_rate = delivered / sent; bounce_rate = hard bounces / (delivered + hard bounces); complaint_rate = complaints / delivered; open_rate = unique human opens / delivered; raw_open_rate includes machine opens (Apple Mail Privacy Protection, image proxy prefetch); click_rate = unique human clicks / delivered; click_to_open_rate = unique human clicks / unique human opens. A rate is null when its denominator is 0. alerts warns above the mailbox providers' thresholds (4% bounces, 0.08% complaints) and is critical above the reputation guard's pause limits. Requires a full_access key.

Authorization: Bearer pdg_…. An API key with full_access. A sending_access key gets 401 restricted_api_key.

Query parameters

Name Type Required Description
days integer No Last N UTC days, today included (default 30). Ignored when from is set. Between 1 and 400.
from string No First UTC day (YYYY-MM-DD). Format: date.
to string No Last UTC day (YYYY-MM-DD, default today). Format: date.
group_by string No day (default) or a dimension (one point per value). A filtered query is grouped by day. One of day, domain, tag, template, broadcast, campaign, provider.
domain_id string No Only this sending domain. UUID.
tag string No Only e-mails with this tag, as name:value.
template_id string No Only e-mails sent from this template. UUID.
broadcast_id string No Only this broadcast (campaign). UUID.
provider string No Only recipients at this mailbox provider. One of gmail, outlook, yahoo, icloud, other.

Request

This endpoint is not in the SDKs yet; call it over HTTP.

cURL
curl -X GET 'https://api.pidgely.com/metrics?days=30&group_by=day' \
  -H "Authorization: Bearer $PIDGELY_API_KEY"

Response

200 OK

JSON
{
  "object": "metrics",
  "from": "2026-09-21",
  "to": "2026-10-20",
  "group_by": "day",
  "filter": null,
  "totals": {
    "key": "total",
    "sent": 1200,
    "delivered": 1188,
    "hard_bounced": 7,
    "soft_bounced": 5,
    "complained": 0,
    "delayed": 14,
    "suppressed": 3,
    "failed": 0,
    "unsubscribed": 4,
    "opens": 1630,
    "machine_opens": 402,
    "unique_opens": 702,
    "unique_human_opens": 455,
    "clicks": 233,
    "bot_clicks": 41,
    "unique_clicks": 160,
    "unique_human_clicks": 131,
    "delivery_rate": 0.99,
    "bounce_rate": 0.0059,
    "soft_bounce_rate": 0.0042,
    "complaint_rate": 0,
    "open_rate": 0.383,
    "raw_open_rate": 0.591,
    "click_rate": 0.1103,
    "click_to_open_rate": 0.2879,
    "unsubscribe_rate": 0.0034
  },
  "data": [
    {
      "key": "2026-10-20",
      "sent": 1200,
      "delivered": 1188,
      "hard_bounced": 7,
      "soft_bounced": 5,
      "complained": 0,
      "delayed": 14,
      "suppressed": 3,
      "failed": 0,
      "unsubscribed": 4,
      "opens": 1630,
      "machine_opens": 402,
      "unique_opens": 702,
      "unique_human_opens": 455,
      "clicks": 233,
      "bot_clicks": 41,
      "unique_clicks": 160,
      "unique_human_clicks": 131,
      "delivery_rate": 0.99,
      "bounce_rate": 0.0059,
      "soft_bounce_rate": 0.0042,
      "complaint_rate": 0,
      "open_rate": 0.383,
      "raw_open_rate": 0.591,
      "click_rate": 0.1103,
      "click_to_open_rate": 0.2879,
      "unsubscribe_rate": 0.0034
    }
  ],
  "alerts": [],
  "thresholds": {
    "bounce_rate_warning": 0.04,
    "complaint_rate_warning": 0.0008,
    "bounce_rate_limit": 0.04,
    "complaint_rate_limit": 0.001
  }
}

Response fields

Name Type Required Description
object string Yes Object type. One of metrics.
from string Yes Format: date.
to string Yes Recipient address (a@x.com or Name <a@x.com>) or a list of them. Up to 50 unique recipients across to, cc and bcc. Format: date.
group_by string Yes —
filter object | null Yes —
totals object Yes —
data object[] Yes Items of this page.
alerts object[] Yes —
alerts[].metric string Yes One of bounce_rate, complaint_rate.
alerts[].level string Yes One of warning, critical.
alerts[].rate number Yes —
alerts[].threshold number Yes —
thresholds object Yes —
thresholds.bounce_rate_warning number Yes —
thresholds.complaint_rate_warning number Yes —
thresholds.bounce_rate_limit number Yes The reputation guard pauses sending above this bounce rate (7-day window).
thresholds.complaint_rate_limit number Yes The reputation guard pauses sending above this complaint rate (7-day window).

Errors

Errors have the shape {"statusCode", "name", "message"}. See Errors for the full list.

Status Name When
401 missing_api_key, restricted_api_key No Authorization: Bearer header, or a sending_access key called an endpoint that needs full_access.
403 invalid_api_key, validation_error The API key is invalid or revoked, or the request is not allowed for this account (unverified domain, plan limit, paused account).
422 validation_error A field is missing or invalid; message names it.
429 rate_limit_exceeded Too many requests per second. Wait for Retry-After seconds.
422 validation_error Unknown group_by, more than one filter, a filtered query not grouped by day, or a range over 400 days.