Skip to main content
Upcoming. These docs cover unreleased development, ahead of any published release. 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.

Playground

Assemble the elements with sample data. Drive the controls, add and arrange elements, and watch events fire live:

Usage

Options

Pass these to whop.tracking.create({ … }), or as props on <Tracking> in React.
string
The company (biz_…) whose people and events this reads. Required. Defaults to "".
string
A scoped token both surfaces read with. Mint ONE token for the whole handle on your server with POST /v1/access_tokens, and set a fresh one with update({ accessToken }) before it expires. Reading the lists needs member:basic:read or company:basic:read; the filter menus’ option counts additionally use stats:read, and the People table’s saved-audience filter uses audience:basic:read — without those the menus simply show fewer options. Omitted, the calls carry the viewer’s own session, which only answers same-origin.
Where person links lead on YOUR site. person is an absolute-URL template with two placeholders, each replaced URL-encoded per row: {personId} is the stable per_… id, identical for the same person on every surface — key your page on it; {identifier} is the most human-meaningful identifier the surface has (a user id or email where known), so it can differ across surfaces. It must be absolute (https://…) — inside an element frame a relative URL would resolve against the frame, so one is treated as unset. Unset, a person click raises personOpened on its element instead. people and events base URLs are accepted for symmetry with the ads handle but nothing under this handle renders them. Defaults to {}.
"today" | "yesterday" | "last_7_days" | "last_14_days" | "last_30_days" | "last_90_days" | "all_time" | "custom"
The window both surfaces cover: today, yesterday, last_7_days, last_14_days, last_30_days, last_90_days, all_time, or custom (pair it with customRange). The elements carry the picker and move this; 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 the window resolves in: account, the account’s own scheduling zone, or local, whichever zone the viewer’s browser is in. account falls back to the viewer’s own when the account has set none. Defaults to "account".
"last_touch" | "first_touch"
Which touch in a person’s journey gets the credit when filtering by source: last_touch, the default, or first_touch. The elements carry the picker and move this, so a host can drive it and read it back off attributionModelChanged. Defaults to "last_touch".
Appearance
Visual customization for this group’s elements. Overrides the global WhopElements({ appearance }); change it live with update({ appearance }).
WhopElementsLocale
Locale for this group’s element UI text. One of the app’s built locales, overriding the global config; any other value falls back to the default locale.

Events

Pass a callback in the create options / React props.

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 Tracking handle, which is the return of whop.tracking.create({ … }) (vanilla) or useTracking() (React).

update

Update the handle live: any of its options (appearance and locale included), propagated to every mounted element. React consumers never call it; updating the namespace component’s props does the same. Signature: (options: Partial<TrackingOptions>) => void

Returned objects

Live objects returned by the methods above. Hold the reference and call it on your page; these are capabilities, not serializable data.

CrossLinksConfig

The consumer-facing shape of an element’s links prop. people/events are base URLs the canonical query params are appended to; person is a template whose {personId} and {identifier} placeholders are replaced with the row’s URL-encoded values.

people

Signature: string | undefined

events

Signature: string | undefined

person

Signature: string | undefined

PeopleFilterBag

The element’s consumer filter vocabulary — camelCase twins of the flat /v1/people params.

source

Signature: string

eventName

Signature: string

customEvent

Signature: string

utmSource

Signature: string

country

Signature: string

device

Signature: string

browser

Signature: string

os

Signature: string

hasPurchased

Signature: string

query

Signature: string

audienceId

Signature: string

eventFrom

Signature: string

eventTo

Signature: string

EventsFilterBag

The element’s consumer filter vocabulary — camelCase twins of the flat /v1/events params.

identifier

Signature: string

event

Signature: string

source

Signature: string

country

Signature: string

utmSource

Signature: string

device

Signature: string

browser

Signature: string

os

Signature: string

from

Signature: string

to

Signature: string

Elements

The elements this group mounts. Each has its own page:

PeopleElement

Everyone the account has seen — visitors and customers resolved from pixel activity, with their source, spend and activity counters. Search, filter by source, event, geography or device, sort any column, and page through. A row click follows links.person when the handle configures it, and otherwise comes back to you as personOpened.

EventsElement

Every event the account measured — page views, leads, purchases and custom pixel events — as a raw, filterable stream. The rows behind any metric: filter by event, source, geography or device over the handle’s window, or search one person’s identifier to read their whole journey. A person cell follows links.person when the handle configures it, and otherwise comes back to you as personOpened.