---
title: "Per-node aggregate of an automation"
method: GET
path: "/automations/{id}/stats"
tags: ["Automations"]
---

# Per-node aggregate of an automation

`GET /automations/{id}/stats`

## Request

- Base URL: `https://sending.dev/api/v1`
- URL: `https://sending.dev/api/v1/automations/{id}/stats`
- Auth: HTTP bearer

How many contacts went through each step, how many were skipped and how many failed, plus enrollments by status. For each step that sends: absolute numbers and email rates (human and non-human opens, clicks, content clicks), the most clicked links with their role and the attributed conversions. Answers the question of whoever designed the flow (at which step half of the people stop, and what they really click); to know what happened to ONE contact use the step log instead. A node with many `skipped` is the first place to look. `?since=<ISO>` restricts to messages sent from that date, `revenue` included (orders attributed to those messages, whenever placed). `revenue`, overall and per node, is what the flow sold: orders attributed by the last click on the content, test runs excluded. Required scope: `automations:read`.

## Path parameters

- `id` string, required: Automation ID.

## Query parameters

- `since` string: ISO 8601: only messages sent from this date.
- `attribution` 'first' | 'last': Conversion model, `last` by default.

## Response `200`

Automation statistics.

- AutomationStats
  - `id` string, uuid, required
  - `name` string, required
  - `status` string, required
  - `since` string, nullable, required: Window applied to sent messages; null = all time.
  - `attribution` 'first' | 'last', required
  - `enrollments` object, required: Real enrollments: test runs do not count in the funnel.
    - `total` integer, required
    - `byStatus` object, required
  - `metrics` object, required: Email totals of the automation; environment and client from human opens only.
    - `sent` integer, required
    - `delivered` integer, required
    - `emailDelivered` integer, required
    - `queued` integer, required
    - `failed` integer, required
    - `openedHuman` integer, required
    - `openedAny` integer, required
    - `machineOpens` integer, required
    - `clicked` integer, required
    - `contentClicks` integer, required
    - `hardBounces` integer, required
    - `softBounces` integer, required
    - `unsubscribed` integer, required
    - `complained` integer, required
    - `openRate` number, nullable, required
    - `clickRate` number, nullable, required
    - `contentClickRate` number, nullable, required
    - `clickToOpenRate` number, nullable, required
    - `unsubscribeRate` number, nullable, required
    - `bounceRate` number, nullable, required
    - `complaintRate` number, nullable, required
    - `deliveryRate` number, nullable, required
    - `readingEnvironment` object[], required
      - `label` string, required
      - `n` integer, required
      - `pct` number, required
    - `topClients` object[], required
      - `client` string, required
      - `n` integer, required
      - `pct` number, required
  - `nodes` AutomationStatsNode[], required
    - `nodeId` string, required
    - `nodeType` string, required
    - `done` integer, required
    - `skipped` integer, required
    - `failed` integer, required
    - `metrics` AutomationNodeEmailMetrics, nullable, required: Only for nodes that sent at least one message.
      - `subject` string, nullable, required
      - `sent` integer, required
      - `delivered` integer, required
      - `emailDelivered` integer, required
      - `queued` integer, required
      - `failed` integer, required
      - `openedHuman` integer, required
      - `openedAny` integer, required
      - `machineOpens` integer, required
      - `clicked` integer, required
      - `contentClicks` integer, required
      - `hardBounces` integer, required
      - `softBounces` integer, required
      - `unsubscribed` integer, required
      - `complained` integer, required
      - `openRate` number, nullable, required
      - `clickRate` number, nullable, required
      - `contentClickRate` number, nullable, required
      - `clickToOpenRate` number, nullable, required
      - `unsubscribeRate` number, nullable, required
      - `bounceRate` number, nullable, required
      - `complaintRate` number, nullable, required
    - `links` LinkStat[], required: The 5 most clicked links in the node's message, with role.
      - `url` string, required: The most clicked raw variant, the recognizable one.
      - `canonicalUrl` string, required
      - `role` string, nullable, required: logo | image | cta | text | social | video | chrome, or null if not classified.
      - `isContent` boolean, required
      - `uniqueClicks` integer, required: Distinct messages with a human click.
      - `totalClicks` integer, required
      - `machineClicks` integer, required: Scanner and proxy clicks: reported, not counted.
      - `firstClickAt` string, date-time, nullable, required
      - `lastClickAt` string, date-time, nullable, required
      - `share` number, nullable, required: Share 0-100 of the scope's unique human clicks.
    - `conversions` object, nullable, required: Conversions attributed to a click on this node.
      - `conversions` integer, required
      - `contacts` integer, required
      - `revenueCents` integer, required
    - `revenue` object, nullable, required: Orders attributed to this node's messages; only for nodes that sent. The rule is in the top-level `revenue.attribution`.
      - `orders` integer, required: Attributed orders, cancelled excluded. A count across all currencies.
      - `revenue` number, nullable, required: Gross total of the attributed orders; `null` with more than one currency (never summed).
      - `refunded` number, nullable, required: Refunds on those orders, declared apart and never subtracted from `revenue`.
      - `currency` string, nullable, required: The only currency involved; `null` with zero orders or more than one currency.
      - `averageOrderValue` number, nullable, required
      - `revenuePerRecipient` number, nullable, required: `revenue` / `delivered`; `null` with no orders, no deliveries or more than one currency.
      - `byCurrency` object[], required: One row per currency, highest revenue first: the numbers to read when there is more than one.
        - `currency` string, required
        - `revenue` number, required
        - `refunded` number, required
        - `orders` integer, required
        - `averageOrderValue` number, nullable, required
  - `links` LinkStat[], required: The most clicked links across the whole automation.
    - `url` string, required: The most clicked raw variant, the recognizable one.
    - `canonicalUrl` string, required
    - `role` string, nullable, required: logo | image | cta | text | social | video | chrome, or null if not classified.
    - `isContent` boolean, required
    - `uniqueClicks` integer, required: Distinct messages with a human click.
    - `totalClicks` integer, required
    - `machineClicks` integer, required: Scanner and proxy clicks: reported, not counted.
    - `firstClickAt` string, date-time, nullable, required
    - `lastClickAt` string, date-time, nullable, required
    - `share` number, nullable, required: Share 0-100 of the scope's unique human clicks.
  - `conversions` EntityConversions, required
    - `attribution` 'first' | 'last', required
    - `lookbackDays` integer, required
    - `total` integer, required
    - `contacts` integer, required
    - `revenueCents` integer, required
    - `currency` string, nullable, required: `null` with mixed currencies: the total cannot be summed.
    - `byName` object[], required
      - `name` string, required
      - `conversions` integer, required
      - `revenueCents` integer, required
    - `byLink` object[], required
      - `url` string, required
      - `conversions` integer, required
      - `contacts` integer, required
      - `revenueCents` integer, required
    - `recent` ConversionRow[], required: The latest 50.
      - `id` string, uuid, required
      - `name` string, required
      - `source` string, required
      - `valueCents` integer, required
      - `currency` string, required
      - `occurredAt` string, date-time, required
      - `contactId` string, uuid, nullable, required
      - `contactEmail` string, nullable, required
      - `touchUrl` string, nullable, required: Clicked link (canonical) it is attributed to.
      - `touchAt` string, date-time, nullable, required
      - `nodeId` string, nullable, required
      - `secondsFromTouch` integer, nullable, required
  - `revenue` RevenueReport, required: Store and API orders attributed to the messages: the last click on the content (not the logo, never an open) within `attribution.windowDays` days before the order. Test runs and cancelled orders excluded.
    - `orders` integer, required: Attributed orders, cancelled excluded. A count across all currencies.
    - `revenue` number, nullable, required: Gross total of the attributed orders; `null` with more than one currency (never summed).
    - `refunded` number, nullable, required: Refunds on those orders, declared apart and never subtracted from `revenue`.
    - `currency` string, nullable, required: The only currency involved; `null` with zero orders or more than one currency.
    - `averageOrderValue` number, nullable, required
    - `revenuePerRecipient` number, nullable, required: `revenue` / `delivered`; `null` with no orders, no deliveries or more than one currency.
    - `byCurrency` object[], required: One row per currency, highest revenue first: the numbers to read when there is more than one.
      - `currency` string, required
      - `revenue` number, required
      - `refunded` number, required
      - `orders` integer, required
      - `averageOrderValue` number, nullable, required
    - `attribution` object, required
      - `model` 'last_content_click', required
      - `windowDays` integer, required: Workspace attribution window: the last content click within these days before the order.
  - `stuck` object[], required: Enrollments stuck on a node that is not waiting for anything.
    - `enrollmentId` string, uuid, required
    - `contactId` string, uuid, required
    - `nodeId` string, required
    - `nodeType` string, nullable, required
    - `since` string, required
    - `minutesStuck` integer, required
  - `lastTestRun` unknown

## Other responses

- `401`: Missing or invalid token.
- `403`: Insufficient scope.
- `404`: Resource not found.

---

[API](https://skmtc.dev/sending/apis/sending-dev-api.md) · [All operations](https://skmtc.dev/sending/apis/sending-dev-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sending/apis/sending-dev-api/revisions/9fe78d2918a1?raw)
