Skip to main content
Upcoming — generated from the latest merged element source; documents unreleased development. Use the channel picker at the top of the sidebar for the docs of a published release.
In development — not yet part of a stable release. A sub-controller in the Ads group: mint it with ads.create('reporting', { … }) (vanilla) or render <Reporting> inside <Ads> (React — mount mints, unmount destroys), then mount its elements off the minted handle. destroy() tears it down — a later create('reporting') boots fresh.

Preview

A live, interactive demo of this sub-controller’s default arrangement with sample data:

Usage

Options

Pass these to ads.create('reporting', { … }) — or as props on <Reporting> in React. Parent-injected props never appear here.
"today" | "yesterday" | "last_7_days" | "last_14_days" | "last_30_days" | "last_90_days" | "all_time" | "custom"
The window every surface reports on: today, yesterday, last_7_days, last_14_days, last_30_days, last_90_days, all_time, or custom (pair it with customRange). The chart carries the picker, and it moves this — so a host can drive the window and read it back off periodChanged. Defaults to "last_14_days".
{ from: string; to: string; } | null
The explicit window, as ISO 8601 instants, used when period is custom. Ignored otherwise. Defaults to null.
"account" | "local"
Which of two zones every figure is reported in: account, the account’s own preferences.ads_scheduling_timezone, or local, whichever zone the viewer’s browser is in. A CHOICE and not a zone, because those two are the only ones the chart’s picker offers — a free IANA zone would report figures in one zone while the picker labelled them as another, and the first touch of the picker would lose it. To report in some third zone, change the account’s. account falls back to the viewer’s own when the account has set none. Defaults to "account".
string
The ISO currency every amount is converted to and labelled in — usd, eur. Unset, it defaults to the account’s preferences.ads_reporting_currency. Defaults to "".
"last_touch" | "first_touch"
Which touch in a buyer’s journey gets the credit: last_touch, the default, or first_touch. Under both, a Whop touch anywhere in the journey wins the Whop bucket — the model only picks the endpoints. The table carries the picker and moves this, so a host can drive it and read it back off attributionModelChanged. Defaults to "last_touch".
string[]
Narrow reporting to these ad campaigns (adcamp_…). Empty reports on the whole account. Overridden by adGroupIds or adIds when either is set. Pass one id for an exact figure: the reporting API scopes by a single source path, so where more than one is given the chart reports on the first alone. Defaults to [].
string[]
Narrow reporting to these ad groups (adgrp_…). Takes precedence over campaignIds. Same single-id caveat. Defaults to [].
string[]
Narrow reporting to these ads (ad_…). The narrowest filter — takes precedence over both others. Same single-id caveat. Defaults to [].
"ads" | "all" | "campaigns" | "ad-groups"
Which table the table element opens on: campaigns, ad-groups, ads, or all for the traffic-source view. all always reports account-wide — the source series exists only at that level — so a filter set alongside it narrows the table but not the chart. Defaults to "campaigns".
string
A scoped token for the surfaces that read under the handle. Only the ad-details overlay takes it from here — it is opened by this controller rather than mounted by you, so unlike table there is no element of your own to set it on. Omitted, its calls carry the viewer’s own session.
string[] | null
Which traffic the chart reports on, as source paths — whop:* for advertising bought through Whop, ext:* and ext:<platform>:* for ads run elsewhere, referrer:* for organic, direct, other. null, the default, reports on Whop advertising alone; [] reports on every source; a non-empty array reports on those. A DIFFERENT axis to campaignIds and friends, which narrow within Whop advertising — spend-derived ratios stay Whop-attributed whatever this is set to, because spend only ever bought Whop ads. The table element’s All tab moves it. Defaults to null.

Events

Pass a callback in the create options / React props.

onEditRequested

The viewer asked to edit something — a row menu, a draft row, or Edit ad in the details overlay. campaignId is always there; adGroupId and adId narrow it to what they clicked. Only raised when useCampaignCreator is off; on, the builder opens over the page instead and this stays quiet. Signature: ((payload: AdsEditTarget) => void)

onLoadingChange

Fired when the grouped loading state changes — true while any mounted element is still loading. Signature: ((loading: boolean) => void)

Methods

Call these on the minted sub handle — the return of ads.create('reporting', { … }).

update

Live-update the sub-controller’s consumer props and on<Event> callbacks. Signature: (options: Partial<ReportingSubOptions>) => void

destroy

Tear the sub-controller down: its mounted elements are destroyed, its runtime state is discarded, and its exclusive slot is freed — a later create("reporting") boots fresh. Signature: () => void

Elements

The elements this sub-controller mounts — each has its own page:

ChartElement

An advertising account’s performance charted over a window you choose, with a picker for which metric to plot — spend, impressions, clicks, or any conversion the account records. Read-only, and the chart only: headline figures belong to whatever surface composes this.

TableElement

An advertising account’s campaigns, ad groups and ads in one table, with the tabs that move between them: pick rows to narrow the level below, search, sort, break the numbers down, choose your columns, and pause, resume, duplicate or delete straight from a row. The window it reports on and the rows it is filtered to live on the handle, so a chart mounted beside it reports on exactly the same thing.

Flow surfaces

These internal elements open automatically during flows (for example a confirmation or verification step). They are not part of the consumer API — you never mount, configure, or subscribe to them directly.
  • AdDetailsElement (adDetails) — A single ad in detail: its creative, its copy, the accounts it runs under and where it sends people. Opened from a row in the table element — it is not mounted directly, and appears over the page rather than inside either frame.