> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Campaign Pulse

> Check whether a campaign is actually running, from the latest provisional figures its sellers reported, and what each verdict means.

Campaign Pulse answers one question: is there fresh evidence that a campaign is
running? A campaign can be active and still deliver nothing, for example when a
seller has not started its line or a creative was rejected. Pulse looks at the
figures each seller reported, not at the campaign's status.

Pulse is provisional. It reads Snapshot figures, which are not final and not
billable. Official reporting, the final figures a seller publishes, is a
separate read: see [Reporting](https://docs.apostra.com/v3/reporting-pipeline.md).

## Read Pulse

Ask for the `pulse` include on a campaign:

```json theme={null}
{ "kind": "campaign", "id": "cmp_123", "include": ["pulse"] }
```

`get` returns `pulse` with the campaign's verdict, its reasons, and one entry
for each live media buy (at most 50; `mediaBuysOmitted` counts the rest). A live
media buy is one that is active: not a draft, paused, ended or archived.

Each media buy entry has:

| Field | Meaning |
| - | - |
| `verdict` | The media buy's verdict (below). |
| `reasonCodes` | Why it has that verdict, for example `snapshot_missing`. |
| `dataThrough` | How far the seller's figures run. `null` when the seller has reported nothing yet. |
| `observedAt` | When Apostra received those figures. |
| `freshness` | `fresh`, `stale` or `missing`, and the `deadline` until which the figures count as fresh. |
| `metrics` | Impressions, clicks and spend, each with an `availability`: `present`, `explicit_zero` (the seller reported zero), or a reason it has no value such as `missing`. |

To show Pulse in a list, ask `search` for it:

```json theme={null}
{ "kind": "campaign", "include": ["pulse"] }
```

Each campaign row then carries `pulse` with only the campaign `verdict`,
`dataThrough` and `nextCheckAt`.

If Pulse cannot be read, the campaign is still returned, and
`unavailableIncludes` names `pulse` with the reason.

## What each verdict means

For a media buy:

| Verdict | Meaning |
| - | - |
| `delivering` | Fresh figures show impressions or spend. |
| `not_delivering` | Fresh figures show zero, reported as zero by the seller. |
| `stale` | The seller's latest figures are older than its reporting schedule allows. |
| `unsupported` | The products this buy booked do not report impressions, clicks or spend. |
| `source_error` | The seller's latest report failed. |
| `not_expected_yet` | The flight has not started, or its first report is not due yet. |
| `unverified` | No usable figures: nothing reported yet, the products declare no reporting schedule, or figures are incomplete. |

For the campaign:

| Verdict | Meaning |
| - | - |
| `not_expected_yet` | No live media buy has started, or the campaign has none. |
| `delivering` | Every started media buy is delivering. |
| `partially_delivering` | At least one is delivering and at least one is not. |
| `not_delivering` | None is delivering, and every started one reported zero. |
| `cannot_verify` | None is delivering, and at least one has no fresh figures to judge. |

Missing figures are never shown as zero. A media buy whose seller has not
reported reads `unverified`, not `not_delivering`, and its metrics are `null`.

## When figures are due

A media buy's reporting schedule comes from the products it booked: how often
each product reports (`available_reporting_frequencies`) and how long after a
period ends its report arrives (`expected_delay_minutes`). A buy reports as
often as its slowest product. Its first report is due one period plus the
longest delay after its flight starts, and its figures stay fresh for one period
plus that delay after their `dataThrough`.

## Keep a view current

`nextCheckAt` is the earliest time a verdict can change with no new report: a
flight starting, a first report falling due, or figures going stale. It is
`null` when only a new report can change a verdict. To keep a page current,
read Pulse again at `nextCheckAt` rather than on a timer.

## Pulse and budgets

Pulse gives a delivery verdict. It does not give pacing figures, and Apostra
does not make budget recommendations from it.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.