# Uplift report

The uplift report measures a single campaign's or a single [Customer Journey](/product/customer-journey/journey-elements/flow-controls/holdout-split/)'s own impact against the holdout you set up for it, the same way [control groups](/product/audience-data-and-segmentation/control-groups/) measure your whole account against its own holdout. A campaign gets a row once it's sent with a holdout share. A journey gets one row for every [Holdout Split](/product/customer-journey/journey-elements/flow-controls/holdout-split/) point it contains.

<Aside type="note" title="Not the control groups Impact report">
Control groups have their own [Impact report](/product/audience-data-and-segmentation/control-groups/analyze-control-group-impact/#view-the-impact-report) in **Settings**, measuring the application's control groups. This uplift report is per campaign or per journey. For a campaign, it's only reachable by [exporting it to CSV](#export-the-report). For a journey, the Holdout Split point also shows [Goal uplift vs holdout](/product/customer-journey/journey-elements/flow-controls/holdout-split/#check-the-uplift-report) in Control Panel.
</Aside>

## When the report updates

The report isn't real time. A daily job computes the previous day's numbers once, at 01:30 UTC, and appends a row. A campaign sent or a journey point passed today shows up in the report tomorrow, not immediately after.

## What counts as treatment and control

**Campaign:** Treatment is every recipient the tracking log marks as sent (`STEP_SEND`). Control is every recipient the tracking log cut for being in the holdout (status code `1028`, the same drop reason as the application's control groups).

**Journey:** Treatment is every user whose tracking-log row at the Holdout Split point shows an output other than **Holdout**. Control is every user whose row shows the **Holdout** output.

Journey users or campaign recipients with no User ID are excluded from both arms of either report type: there's no identity to match them against a holdout draw or a conversion.

## Goal and attribution window

**Campaign:** The goal and window come from the application's Conversion Goals. When more than one is configured, the report uses the shortest attribution window among them, so a send is never credited with a distant, unrelated conversion.

**Journey:** The goal is the journey's own Goal points, and the window is the journey's Conversion window setting (7 days if the journey doesn't set one). The window starts from the moment each user individually passed the Holdout Split point, not from a shared clock: the Holdout arm never reaches a send point, so there's no send time to anchor the window to instead.

Both exclude message-engagement events (opens, clicks, and similar) from the goal. The holdout arm never receives a message to react to, so counting engagement would only show that a message went out, not what it achieved. [Control group analytics](/product/audience-data-and-segmentation/control-groups/#analyze-control-group-impact) excludes them for the same reason.

## Metrics in the report

| Metric | What it means |
|---|---|
| **Uplift %** | The percentage difference between the treatment and control conversion rates, relative to the control rate. Same formula as the Uplift of the application's control groups. |
| **Incremental events** | The estimated number of additional events the treatment arm generated beyond what the control arm's per-user rate implies, scaled to the treatment population. Same formula as [Conversions driven by messaging](/product/audience-data-and-segmentation/control-groups/#view-the-impact-report). |
| **% of treatment** | Incremental events as a share of all events the treatment arm generated. |
| **Z-score, P-value, Confidence %** | The same two-proportion significance test the application's control groups use. |
| **Significance** | **Significant**, **Not significant**, or **Not enough data**. It reads as not enough data when either arm has fewer than 10 conversions or fewer than 10 non-conversions. |
| **Treatment revenue / Control revenue** | Money each arm brought in on the report's goal event, kept separately per currency. |
| **Incremental revenue** | The money version of Incremental events: revenue per user in treatment minus control, scaled to the treatment population, per currency. |
| **Revenue tracked** | Whether the revenue source for this event was actually configured, not guessed. See [Revenue in the report](#revenue-in-the-report). |

<Aside type="note">
**Uplift %** is built on `uniqExact` user counts, so one unusually active user can't skew it. **Incremental events** counts every event without capping per user, on purpose, to match how the application's control groups count events. That means a single very active treatment user can pull that one number up without moving Uplift % at all. When the two disagree, trust Uplift %.
</Aside>

## Revenue in the report

Treatment, control, and incremental revenue are read for the same goal event as the rest of the row, through the same query that finds the treatment and control arms for conversions. The money is always about the same journey users or campaign recipients, over the same attribution window, never a separate calculation that could drift from the conversion numbers next to it.

### Revenue is kept per currency, never converted

Pushwoosh keeps only today's exchange rates, refreshed daily, not a rate history. Converting a 45-day-old window at today's rate would turn a real number into a guess, so revenue isn't converted at all: **Treatment revenue**, **Control revenue**, and **Incremental revenue** each hold one amount per currency instead of one combined total. An event that doesn't name a currency is bucketed under `unknown`, so two accounts' unlabeled revenue never merges into one number.

### Revenue tracked tells you whether the source was configured

Revenue tracking is set up on a small share of applications. Without a way to tell "not configured" apart from "made nothing," an application that never set it up would show every campaign as a loss instead of as unmeasured.

Pushwoosh reads an event's revenue from three places, in order, the same order the conversion dashboard uses so the two never disagree:

1. The built-in `PW_Conversion` event's own `value` and `currency` fields.
2. An event revenue mapping you configured for that event.
3. The legacy `__amount` and `__currency` attributes on the event, if neither of the above applies.

**Revenue tracked** is true only for the first two sources. The third still reports a dollar amount, since the data is there to read, but leaves the flag off: nobody configured that event's revenue, the report is only guessing from a compatibility pair.

## How far back the report can look

A campaign's arms come from the channels tracking log, which keeps about 45 days of history. A journey's arms come from a longer-lived tracking log that keeps 180 days. A send or a journey point pass older than its source's window has nothing left to read, so the report has no row for it. The report table itself keeps 90 days of its own rows before they age out.

## Export the report

[Export the uplift report](/developer/api-reference/statistics-api/export-uplift-report/) to a CSV file, one row per campaign or journey holdout point per goal event, including the per-currency revenue columns above.