Skip to main content
GET /api/v1/campaigns/{campaignId}/analytics answers with money, per-channel money, and measured performance.

Money

These always reconcile:
  • spent — what actually left the account: PAID and every status after it.
  • reserved — committed when you approved a placement, not yet paid out.
  • remaining — uncommitted; a further approval can still spend it.
perChannel breaks the same money down per placement: the amount agreed with the channel owner, and a status saying whether it was paid, is merely held, or came to nothing. Placements with no agreed price are absent.

Performance

dataAvailable: false means nothing has been measured yet — views, reactions and cpm will all be absent. Throughout this object, a metric that has not been measured is null, never 0. Zero would be a measurement; null is the absence of one.

Two clocks that do not run together

This is the single most important thing to understand about these numbers.

Views and reactions

Measured by the parser on the published posts. They converge to the figure reached roughly 48 hours after each post goes up, and then stop — tracking retention ends there and the placement completes. A settled result, not a live counter.

Clicks

Measured on our own redirect: every link in a published post points at go.aflux.ai first, so a click is counted before the reader is sent on to you. They keep accruing for as long as the post stays up.
Because views stop at ~48h while clicks keep arriving, ctr drifts downward over the weeks after a campaign finishes. Compare it between campaigns of similar age — never between a fresh one and a finished one.

Reading each field

Always read cpm and costPerClick next to measuredPlacements. While some placements are still unmeasured, both are a partial price — not the campaign’s final cost per view. cpm divides the measured placements’ payouts by their own views; it is not the campaign’s whole spent over a measured subset of its audience.

Per-placement figures

The same distinction repeats on each placement, where it is easier to reason about: expectedViews resolves to avgAdReach24h, or avgReach when ad posts were never measured on that channel. The same number the campaign’s expected-views total and the per-deal price cap are computed from. It is null — never 0 — when the channel carries no usable reach at all.