Analytics
One call returns sent, delivered, opened, clicked and more as a time series, totals and a breakdown, for transactional mail, campaigns and sequences.
Query
curl "https://api.runearc.com/v1/analytics?range=30d&type=campaign&by=source" \
-H "Authorization: Bearer $RUNEARC_API_KEY"| Parameter | Values | Description |
|---|---|---|
| range | 7d, 30d (default), 90d, custom | Presets end today (UTC). |
| from, to | YYYY-MM-DD | For range=custom, both UTC and inclusive. At most 366 days. A range of 2 days or less is bucketed hourly, otherwise daily. |
| type | transactional, campaign, sequence | Only that kind of send. |
| source_id | string | One campaign or sequence id. |
| step_id | string | One sequence step or campaign email. |
| provider | ses, kumo, unknown | The transport that sent it. |
| subscriber | email or seg_... | One address, or a segment. |
| by | source (default), type, provider | How rows are grouped. At most 200 rows. |
Response
| Field | Type | Description |
|---|---|---|
| range, filters, availability | object | The resolved range and interval, the filters applied, and whether each metric has data. |
| totals | object | sent, delivered, bounced, complained, opened, clicked, unsubscribed, conversions, revenue_cents. |
| rates | object | delivery, bounce, complaint (of sent), open, click, unsubscribe (of delivered). null when the denominator is 0. |
| series | array | One point per bucket: t and the same counters. |
| rows | array | The breakdown: type, source_id, step_id, provider, label and the counters. |
Counts are unique per recipient, ignore bot traffic (see Tracking) and are bucketed at the
time of the event. Conversions and revenue come from goals. Analytics cover the whole
workspace, so a key limited to sending or to one inbox is refused with insufficient_scope; use a full key.
CLI and MCP
runearc analytics --range 30d --type campaign --by source
runearc analytics --range custom --from 2026-11-01 --to 2026-11-07 --subscriber ada@example.comThe MCP tool is get_analytics.
Errors
| Code | Status | Meaning and fix |
|---|---|---|
| invalid_range | 400 | Use 7d, 30d, 90d, or custom with from and to as YYYY-MM-DD, at most 366 days, not in the future. |
| invalid_type, invalid_provider, invalid_breakdown | 400 | Use a value from the table above. |
| invalid_subscriber, segment_unavailable | 400 | Send an email address or an existing segment id. |
| insufficient_scope | 403 | Use a full access key or a role that can view logs. |
Per message delivery state is on Emails API and Webhooks.