Skip to content

Tracking API

REST endpoints for the Tracking area of Lepsto.

The Tracking area publishes 45 REST endpoints. Paths are relative to https://api.lepsto.com; see Authentication for the required header.

GET/tracking/catalog

List the event-name catalog for the current product with counts, first/last seen, sampled prop keys, and status.

MCP tool: tracking_event-names_list

Parameters

NameInTypeRequiredDescription
statusquery
stringone of: active, archived
—
Filter by status; omit for all
searchquery
string
—
Case-insensitive substring match on the event name
sortquery
stringone of: count, last_seen, first_seen, name
—
Sort column (default count)
orderquery
stringone of: asc, desc
—
Sort direction (default desc)

Response

Returns object.

FieldTypeAlwaysDescription
names
object[]
•
The matching catalogue entries, ordered by the requested sort
POST/tracking/catalog/archive

Archive an event name (hides it from dashboards only; ingestion and counts continue unchanged).

MCP tool: tracking_event-names_archive

Parameters

NameInTypeRequiredDescription
namebody
string
•
The event name to archive/unarchive

Response

Returns object.

FieldTypeAlwaysDescription
name
string
•
Event name whose status was changed
status
stringone of: active, archived
•
The status as it now stands: `archived` hides the name from pickers and reports, `active` restores it
POST/tracking/catalog/set-conversion

Mark an event name as a conversion, or unmark it. A marked name publishes `tracking/conversion.recorded` every time that event is recorded, which a workflow can trigger on; an unmarked one publishes nothing. Ingestion, counts and dashboards are unchanged either way.

MCP tool: tracking_event-names_set-conversion

Parameters

NameInTypeRequiredDescription
namebody
string
•
The event name to mark or unmark
isConversionbody
boolean
•
true makes this event name a workflow trigger; false stops it being one

Response

Returns object.

FieldTypeAlwaysDescription
name
string
•
Event name the conversion flag was applied to
isConversion
boolean
•
The flag as it now stands after the change
POST/tracking/catalog/unarchive

Unarchive an event name (restores its visibility in dashboards).

MCP tool: tracking_event-names_unarchive

Parameters

NameInTypeRequiredDescription
namebody
string
•
The event name to archive/unarchive

Response

Returns object.

FieldTypeAlwaysDescription
name
string
•
Event name whose status was changed
status
stringone of: active, archived
•
The status as it now stands: `archived` hides the name from pickers and reports, `active` restores it
GET/tracking/domains

List the product's custom domains and tracking-host bindings

MCP tool: tracking_domains_list

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
domains
object[]
•
The product's domains as the platform vouches for them — the set a new tracking host may be claimed under
bindings
object[]
•
Tracking-host bindings this toolkit currently holds across those domains
POST/tracking/domains

Claim a first-party tracking host under a product domain

MCP tool: tracking_domains_create

Parameters

NameInTypeRequiredDescription
domainIdbody
string
•
Product domain to claim the tracking host under, as listed in `domains[].domainId` by tracking_domains_list
hostbody
string
—
Bare hostname to serve tracking from, which must sit under the chosen domain (e.g. analytics.example.com); a suggestion is used when omitted
recordsbody
object[]
—
DNS records to request instead of the default CNAME to the tracking edge; leave unset unless the domain needs custom records

Response

Returns object.

FieldTypeAlwaysDescription
binding
object
•
The binding as just claimed; it starts `pending` and goes `active` once the DNS is observed live
instructions
string[]
•
Ordered, human-readable steps for publishing the DNS the claim needs; empty when the platform manages the domain itself
DELETE/tracking/domains/:bindingId

Release a tracking-host binding

MCP tool: tracking_domains_delete

Parameters

NameInTypeRequiredDescription
bindingIdpath
string
•
Id of the tracking-host binding to act on, as returned in `bindings[].bindingId` by tracking_domains_list

Response

Returns object.

FieldTypeAlwaysDescription
ok
booleanone of: true
•
Always true — the release succeeded; a failure arrives as an error, not as false
GET/tracking/domains/:bindingId

Get one tracking-host binding and its status

MCP tool: tracking_domains_get

Parameters

NameInTypeRequiredDescription
bindingIdpath
string
•
Id of the tracking-host binding to act on, as returned in `bindings[].bindingId` by tracking_domains_list

Response

Returns object.

FieldTypeAlwaysDescription
host
string
•
Fully-qualified tracking host this binding serves, e.g. analytics.example.com
status
stringone of: pending, active, failed
•
Where the claim stands: `pending` while DNS has not been observed live, `active` once it serves, `failed` when the check gave up
records
array
•
DNS records the platform expects to see published for this host, as returned when the binding was claimed
domainId
string
•
Product domain this tracking host sits under
bindingId
string
•
Id of the tracking-host binding to act on, as returned in `bindings[].bindingId` by tracking_domains_list
createdAt
string (date-time)
•
When the binding was claimed
productId
string
•
Product the binding belongs to
updatedAt
string (date-time)
•
When the binding last changed status or records
statusDetail
string | null
•
Human-readable reason behind the current status, such as the DNS error that made it fail; null while there is nothing to report
ownerExtension
string
•
Extension that claimed the binding; tracking bindings are owned by this toolkit
POST/tracking/domains/:bindingId/verify

Run an immediate liveness check for a pending binding

MCP tool: tracking_domains_verify

Parameters

NameInTypeRequiredDescription
bindingIdpath
string
•
Id of the tracking-host binding to act on, as returned in `bindings[].bindingId` by tracking_domains_list

Response

Returns object.

FieldTypeAlwaysDescription
host
string
•
Fully-qualified tracking host this binding serves, e.g. analytics.example.com
status
stringone of: pending, active, failed
•
Where the claim stands: `pending` while DNS has not been observed live, `active` once it serves, `failed` when the check gave up
records
array
•
DNS records the platform expects to see published for this host, as returned when the binding was claimed
domainId
string
•
Product domain this tracking host sits under
bindingId
string
•
Id of the tracking-host binding to act on, as returned in `bindings[].bindingId` by tracking_domains_list
createdAt
string (date-time)
•
When the binding was claimed
productId
string
•
Product the binding belongs to
updatedAt
string (date-time)
•
When the binding last changed status or records
statusDetail
string | null
•
Human-readable reason behind the current status, such as the DNS error that made it fail; null while there is nothing to report
ownerExtension
string
•
Extension that claimed the binding; tracking bindings are owned by this toolkit
GET/tracking/entitlement-drops/current

Report the /collect events and session recordings this product lost this UTC month because billing refused to store them (trial monthly limit reached, billing paused). Counts events that were never stored; tracking_reports_event_volume counts the events that were. Returns: { month, drops: { droppedEvents, droppedBatches, droppedRecordings, firstDroppedAt, lastDroppedAt, lastReason, upgradeUrl, plan } | null }. Fails when: the call carries no product.

MCP tool: tracking_entitlement-drops_get

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
drops
object | null
•
Null when no event and no session recording was refused this month.
month
string
•
First day of the current UTC month the figures cover, YYYY-MM-DD, e.g. 2026-09-01.
GET/tracking/googleads/connection

Google Ads connection status for the current product: whether a Google Ads account is connected and which account (loginCustomerId / customerId), or whether it still needs account selection or re-auth.

MCP tool: tracking_googleads_connection_status

Parameters

No parameters.

Response

Returns object.

GET/tracking/googleads/feedback/config

Get the Google Ads conversion-feedback config for the current product (enabled, mode, lookbackDays, event→conversion-action rules, accountCurrency — the connected account's currency, best-effort, null if unavailable — useful for defaulting a fixed-value rule's currency, and dynamicValueEvents — the revenue-eligible event-names that may use the Dynamic value source).

MCP tool: tracking_googleads_feedback_config_get

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
mode
stringone of: existing_pixel, fresh_pixel
•
How the uploads coexist with the account's own tag: existing_pixel means the Google tag also records these conversions, so send only to actions the tag does not already cover; fresh_pixel means these uploads are the only source.
rules
object[]
•
Which tracked events become which Google Ads conversion action, and where each one takes its money value from. Disabled rules stay listed.
enabled
boolean
•
Whether conversions are being sent to Google Ads at all. False leaves every rule below in place but uploads nothing.
productId
string
•
The tenant this configuration belongs to. Never supplied by a caller — it comes from the authenticated identity.
lookbackDays
number
•
How many days back each pass looks for conversions to send, and how far back a click may be matched. Google rejects clicks older than about 90 days.
accountCurrency
string | null
•
Currency of the connected Google Ads account, as a three-letter ISO 4217 code such as EUR. Null when the account could not be read.
dynamicValueEvents
string[]
•
The event names that may use the Dynamic value source, because revenue is known for them. Any other event needs a fixed amount.
enhancedConversions
boolean
•
Whether a stored email or phone number is sent alongside the click, so Google can match conversions the click id alone would miss.
POST/tracking/googleads/feedback/config

Set the Google Ads conversion-feedback config (enable/disable, mode, lookback, rules, enhancedConversions). enhancedConversions adds hashed email/phone as additive match keys alongside gclid. Returns the config plus safety guidance. Rules are validated against the account's conversion actions.

MCP tool: tracking_googleads_feedback_config_set

Parameters

NameInTypeRequiredDescription
enabledbody
boolean
—
Master switch for conversion feedback (default off)
modebody
stringone of: existing_pixel, fresh_pixel
—
existing_pixel = fill gaps; fresh_pixel = our data only
lookbackDaysbody
integer
—
Click lookback window for gclid match (<=90)
rulesbody
object[]
—
Map a tracked event to a Google conversion action with a per-rule value (net revenue or a fixed amount)
enhancedConversionsbody
boolean
—
Enhanced conversions: also send hashed email/phone as additive match keys alongside gclid (default off)

Response

Returns object.

FieldTypeAlwaysDescription
config
object
•
The config as it now stands after the write, with server-side normalisation applied
guidance
string[]
•
Plain-language safety notes about what this combination of mode and match keys will do to the connected account
GET/tracking/googleads/feedback/conversion-actions

List the connected Google Ads account's conversion actions (resource, name, category, status) so you can map a tracked event to a Google conversion action with a per-rule value (net revenue or a fixed amount).

MCP tool: tracking_googleads_conversion_actions

Parameters

No parameters.

Response

Returns object[].

Item fieldTypeAlwaysDescription
id
string
•
—
name
string
•
—
status
string
•
—
category
string
•
—
resourceName
string
•
—
POST/tracking/googleads/feedback/run

Manually run one conversion-feedback upload pass for the current product now (uploads newly-attributed conversions across all enabled rules since the last run). Useful for testing; the daily cron runs this automatically.

MCP tool: tracking_googleads_feedback_run

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
runId
string
•
This one upload pass. Match the completion event back to this step on it, not on productId: the daily cron pass and a manual run on the same day are two passes of the same product.
failed
number
•
Rows Google rejected in this pass.
matched
number
•
Of those, the ones that had a usable click id and a value, so a payload was actually built for them.
noGclid
number
•
Conversions dropped because no Google click could be tied to the person. A high count here is a tagging problem, not a Google one.
skipped
stringone of: disabled, no_rules, not_connected
—
Present only when the pass did no work, and says why: feedback is switched off, no rule is enabled, or no Google Ads account is connected. Absent on a pass that ran.
selected
number
•
Conversions in the lookback window that an enabled rule applied to.
uploaded
number
•
Rows Google accepted in this pass.
productId
string
•
The tenant whose conversions this pass uploaded.
zeroValue
number
•
Conversions held back because their money value had not landed yet. They are retried on a later pass.
partialFailureError
string
—
Google's own rejection detail, passed through unchanged, when it refused part of the batch. Absent when it accepted everything.
GET/tracking/googleads/feedback/status

Google Ads conversion-feedback status for the current product: enabled/mode, rule count, cumulative uploaded/failed counts, last-run coverage (selected vs matched vs uploaded, plus noGclid so gclid-match coverage is visible), safety guidance, accountCurrency (the connected account's currency, best-effort, null if unavailable), and dynamicValueEvents (the revenue-eligible event-names that may use the Dynamic value source).

MCP tool: tracking_googleads_feedback_status

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
mode
stringone of: existing_pixel, fresh_pixel
•
How the uploads coexist with the account's own tag: existing_pixel means the Google tag also records these conversions; fresh_pixel means these uploads are the only source.
failed
number
•
Rows Google has rejected since this product was connected, across every pass.
enabled
boolean
•
Whether conversions are being sent to Google Ads at all.
lastRun
object | null
•
Coverage of the most recent pass. Null when no pass has run for this product yet.
guidance
string[]
•
Plain-language warnings about the current setup, such as double counting when the Google tag already records the same conversion. Empty when nothing needs saying.
uploaded
number
•
Rows Google has accepted since this product was connected, across every pass.
ruleCount
number
•
How many event-to-conversion-action rules are configured, enabled or not.
lookbackDays
number
•
How many days back each pass looks for conversions to send, and how far back a click may be matched.
accountCurrency
string | null
•
Currency of the connected Google Ads account, as a three-letter ISO 4217 code such as EUR. Null when the account could not be read.
dynamicValueEvents
string[]
•
The event names that may use the Dynamic value source, because revenue is known for them.
enhancedConversions
boolean
•
Whether a stored email or phone number is sent alongside the click, so Google can match conversions the click id alone would miss.
GET/tracking/googleads/feedback/uploads

List the most recent Google Ads offline-conversion uploads for the current product (per-row ledger: conversionKey, gclid, conversionAction, conversionDatetime, valueMicros, currency, orderId, status, error, uploadedAt). Newest first. Query: limit (default 100, max 500).

MCP tool: tracking_googleads_feedback_uploads

Parameters

NameInTypeRequiredDescription
limitquery
integer
—
—

Response

Returns object[].

Item fieldTypeAlwaysDescription
error
string | null
•
—
gclid
string
•
—
status
string
•
—
orderId
string
•
—
currency
string
•
—
uploadedAt
string
•
—
valueMicros
number
•
—
conversionKey
string
•
—
conversionAction
string
•
—
conversionDatetime
string
•
—
GET/tracking/googleads/reports/roas

Reads what each Google Ads campaign cost and what it earned back, with ad groups and ads nested underneath. Return on ad spend and cost per customer are worked out at campaign level from the revenue we traced ourselves; spend, impressions, clicks and Google's own conversion counts are there at every level. Each account currency is reported separately and never added to another. Covers the last 30 days unless a window is given.

MCP tool: tracking_googleads_roas_report

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Start of the reporting window, inclusive. ISO-8601 date or timestamp, e.g. 2026-01-01. Omit to start 30 days before the end of the window.
toquery
string (date-time)
—
End of the reporting window, inclusive. ISO-8601 date or timestamp; a date-only value covers that whole day, so revenue after midnight is not cut off. Omit to end now.
modelquery
stringone of: last_click, first_click
—
Which touchpoint gets the credit for a conversion: the last paid click before it, or the first. Defaults to last_click.
lookbackDaysquery
integer
—
How far back before a conversion a paid click may sit and still earn the credit, in days. 1-365, silently clamped into that range; defaults to 30.
domainquery
string
—
Restrict to conversions tracked on this installed site, e.g. acme.com. Omit to cover every domain of the product.
customerIdquery
string
—
Restrict to one Google Ads account, by its customer id without dashes. Omit to cover every connected account.

Response

Returns object.

FieldTypeAlwaysDescription
to
string (date-time)
•
End of the window this report covers, echoed back as an ISO-8601 UTC timestamp.
from
string (date-time)
•
Start of the window this report covers, echoed back as an ISO-8601 UTC timestamp.
model
stringone of: last_click, first_click
•
Which touchpoint earned the credit in these numbers: the last paid click before the conversion, or the first.
stale
boolean
•
True when any account below is running on cost older than the freshness threshold, or on no cost at all — read this before acting on the numbers.
domain
string | null
•
The installed site this report was restricted to; null when it covers every domain of the product.
accounts
object[]
•
One entry per Google Ads account and currency. Kept apart on purpose: amounts in different currencies are never added together.
currency
string | null
•
ISO-4217 code every amount in this report is expressed in, when all accounts share one; null when the report spans several currencies.
computedAt
string (date-time)
•
When this report was calculated (ISO-8601 UTC). The figures are a snapshot at this moment, not live.
customerId
string | null
•
Google Ads account this whole report covers, when it covers exactly one; null when it spans several accounts.
lookbackDays
number
•
How far back before a conversion a paid click was allowed to sit and still earn the credit, in days.
costLastSyncedAt
string (date-time) | null
•
Oldest moment cost was pulled from Google Ads across the accounts below (ISO-8601 UTC); null when any account has never synced.
unmatchedAttributed
object[]
•
Revenue we tracked but could not tie to any Google Ads campaign, grouped by the utm_campaign we saw. A long list here means the ad tagging needs fixing, not that the ads failed.
GET/tracking/googleads/reports/us-vs-platform

Puts our own revenue and customer counts beside the conversions Google reports, one row per campaign, so the gap between the two is visible. Both sides stay in the account currency and are never converted. Use it to decide which number to trust before acting on either. Covers the last 30 days unless a window is given.

MCP tool: tracking_googleads_us_vs_platform

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Start of the reporting window, inclusive. ISO-8601 date or timestamp, e.g. 2026-01-01. Omit to start 30 days before the end of the window.
toquery
string (date-time)
—
End of the reporting window, inclusive. ISO-8601 date or timestamp; a date-only value covers that whole day, so revenue after midnight is not cut off. Omit to end now.
modelquery
stringone of: last_click, first_click
—
Which touchpoint gets the credit for a conversion: the last paid click before it, or the first. Defaults to last_click.
lookbackDaysquery
integer
—
How far back before a conversion a paid click may sit and still earn the credit, in days. 1-365, silently clamped into that range; defaults to 30.
domainquery
string
—
Restrict to conversions tracked on this installed site, e.g. acme.com. Omit to cover every domain of the product.
customerIdquery
string
—
Restrict to one Google Ads account, by its customer id without dashes. Omit to cover every connected account.

Response

Returns object.

FieldTypeAlwaysDescription
to
string (date-time)
•
End of the window this comparison covers, echoed back as an ISO-8601 UTC timestamp.
from
string (date-time)
•
Start of the window this comparison covers, echoed back as an ISO-8601 UTC timestamp.
model
stringone of: last_click, first_click
•
Which touchpoint earned the credit on OUR side of the comparison: the last paid click before the conversion, or the first. Google always uses its own model.
stale
boolean
•
True when any account below is running on cost older than the freshness threshold, or on no cost at all — read this before acting on the numbers.
domain
string | null
•
The installed site this comparison was restricted to; null when it covers every domain of the product.
accounts
object[]
•
One entry per Google Ads account and currency, each holding its per-campaign comparison rows. Currencies are never added together.
currency
string | null
•
ISO-4217 code every amount in this report is expressed in, when all accounts share one; null when the report spans several currencies.
computedAt
string (date-time)
•
When this comparison was calculated (ISO-8601 UTC). The figures are a snapshot at this moment, not live.
customerId
string | null
•
Google Ads account this whole report covers, when it covers exactly one; null when it spans several accounts.
lookbackDays
number
•
How far back before a conversion a paid click was allowed to sit and still earn the credit on our side, in days.
costLastSyncedAt
string (date-time) | null
•
Oldest moment cost was pulled from Google Ads across the accounts below (ISO-8601 UTC); null when any account has never synced.
POST/tracking/googleads/sync

Pull the current product's Google Ads campaign/ad-group/ad structure and daily spend/metrics into the reporting tables now (backfill window). Returns per-table row counts. Skips gracefully if the account is pending selection or needs re-auth.

MCP tool: tracking_googleads_sync_now

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
rows
object
•
How much this sweep wrote, split by what it wrote. Re-running the same window updates rows in place rather than adding, so these are rows touched, not rows gained. All zero when the status is skipped.
runId
string
•
This one sync run. Match the completion event back to this step on it, not on productId: a product syncs many times, and the daily cron run and a manual one are different runs.
reason
string
—
Why nothing was written, when the status is skipped: the account is not chosen yet, the authorisation expired, or Google was unavailable. Absent on a sweep that ran.
status
stringone of: ok, skipped
•
Whether the sweep ran. skipped means the Google Ads account could not be reached and nothing at all was written.
window
object
•
The range of days this sweep read spend and metrics for.
productId
string
•
The tenant whose Google Ads account was swept.
lastSyncedAt
string (date-time) | null
•
When the sweep finished. Null when nothing was written.
GET/tracking/googleads/tracking-health

Google Ads URL-tracking health for the current product over a date range: how many Google paid clicks arrived, how many carried our ValueTrack URL parameters (marker _lt_campaign) vs how many were UNTAGGED (template not installed / broken), the breakage rate, whether the template is verified live, first/last untagged times, sample offending landing URLs. Read-only; computed on the fly from stored events (no Google Ads API call). dataQuality describes how complete the figures above are and holds no metric of its own: dataQuality.cookielessPaidClicks is how many of the paid clicks arrived cookieless (the visitor declined consent) — counted INSIDE paidClicks, never added to it, because a cookieless paid click is a real click and belongs in the breakage denominator. It is broken out so breakageRate is not read as one homogeneous population. Clicks from sites running no consent banner at all are NOT counted as cookieless: nobody was ever asked there, which is not the same as being told no.

MCP tool: tracking_googleads_tracking_health

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Range start (ISO); defaults to 30 days ago
toquery
string (date-time)
—
Range end (ISO); defaults to now

Response

Returns object.

FieldTypeAlwaysDescription
to
string (date-time)
•
End of the range these figures cover, as an instant.
from
string (date-time)
•
Start of the range these figures cover, as an instant. Echoes back the range that was asked for.
installed
boolean
•
Whether the tracking template has been seen working live: true once at least one tagged click has arrived.
truncated
boolean
•
Whether the sample above was cut short. True means more untagged URLs exist than are listed.
paidClicks
number
•
Google paid clicks that arrived on the site in this range. The denominator for everything below.
dataQuality
object
•
How complete the figures above are. Holds no metric of its own — it exists so the breakage rate is not read as one uniform population.
breakageRate
number
•
Share of paid clicks that arrived untagged, between 0 and 1. Anything much above zero means the tracking template needs fixing.
taggedClicks
number
•
Of those, the ones that arrived carrying our URL tracking parameters, so the campaign behind them is known.
lastUntaggedAt
string (date-time) | null
•
When the most recent untagged click arrived. Close to now means the breakage is still live. Null when none did.
untaggedClicks
number
•
Of those, the ones that arrived without our parameters, so the money spent on them cannot be attributed. This is what the tracking template being missing or broken looks like.
firstUntaggedAt
string (date-time) | null
•
When the first untagged click of the range arrived — roughly when the breakage started. Null when none did.
sampleUntaggedUrls
string[]
•
A handful of the actual landing URLs that arrived untagged, to paste into a browser while fixing the template. Real customer URLs, query strings included.
GET/tracking/heatmaps/page

Get the heatmap of one page for one device: where visitors clicked (per element, on a 50x50 grid inside it), how far they scrolled, and which recording to draw the page from. sessions counts the recordings of the period and filters with a click or a scroll sample on the page — the same recordings tracking_recordings_list returns with the same device, campaign, source and conversion filters. scroll.reached[i] is a share of the sessions that reported a scroll depth on the page (a click-only session reports none), reaching (i+1)*5% of its height. Below 10 sessions the map is withheld: belowThreshold is true, clicks and scroll.reached are empty. Returns: { sessions, belowThreshold, clicks, scroll, background }. Fails when: the period is longer than 30 days; the call carries no product.

MCP tool: tracking_heatmaps_get

Parameters

NameInTypeRequiredDescription
pageKeyquery
string
•
The page, as tracking_heatmaps_pages returns it: host + normalized path, e.g. shop.example.com/pricing.
fromquery
string (date-time)
•
Start of the period, ISO 8601 (e.g. 2026-10-01T00:00:00Z): recordings that started at or after it. At most 30 days before `to`.
toquery
string (date-time)
•
End of the period, ISO 8601: recordings that started at or before it.
utmCampaignquery
string
—
Only recordings whose entry page carried this utm_campaign, e.g. spring.
utmSourcequery
string
—
Only recordings whose entry page carried this utm_source, e.g. google.
convertedquery
boolean
—
true: only sessions with a conversion or a payment; false: only sessions without one. Omit for both.
devicequery
stringone of: desktop, tablet, mobile
•
Required: a map is drawn for one kind of device (desktop, tablet or mobile), since layouts differ.

Response

Returns object.

FieldTypeAlwaysDescription
clicks
object[]
•
At most 300 elements, most clicked first.
scroll
object
•
How far down the page the sessions scrolled.
sessions
integer
•
Recordings of the period, device and filters with a click or a scroll sample on this page.
background
object | null
•
The latest recording of this device (any time in retention) whose segment loaded this page with a full snapshot at its start. Null when none: a page only ever reached by in-app navigation has no picture of its own.
belowThreshold
boolean
•
True when sessions < 10: clicks and scroll.reached are then empty and medianDocHeight null.
GET/tracking/heatmaps/pages

List the pages of the current product that have heatmap data (clicks, scroll depth) from session recordings, most sessions first. A page is host + normalized path (no query, no hash, ids replaced by *). Filter by period (required, at most 30 days), device, campaign, source, conversion and page text; cursor-paged. sessions counts the recordings with a click or a scroll sample on the page, selected like tracking_recordings_list with the same filters. Returns: { pages, nextCursor }. Fails when: the period is longer than 30 days; cursor is not one this tool issued; the call carries no product.

MCP tool: tracking_heatmaps_pages

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
•
Start of the period, ISO 8601 (e.g. 2026-10-01T00:00:00Z): recordings that started at or after it. At most 30 days before `to`.
toquery
string (date-time)
•
End of the period, ISO 8601: recordings that started at or before it.
utmCampaignquery
string
—
Only recordings whose entry page carried this utm_campaign, e.g. spring.
utmSourcequery
string
—
Only recordings whose entry page carried this utm_source, e.g. google.
convertedquery
boolean
—
true: only sessions with a conversion or a payment; false: only sessions without one. Omit for both.
devicequery
stringone of: desktop, tablet, mobile
—
Only recordings from this kind of device: desktop, tablet or mobile. Omit for all.
qquery
string
—
Only pages whose key contains this text, case-insensitively, e.g. /pricing.
cursorquery
string
—
Continue a previous page: pass the nextCursor it returned.
limitquery
integer
—
Pages per page of results, 1 to 100 (default 50).

Response

Returns object.

FieldTypeAlwaysDescription
pages
object[]
•
Most sessions first.
nextCursor
string | null
•
Pass back as cursor for the next page. Null on the last page.
GET/tracking/identity/health

Identity match-rate metric: share of identified profiles and share with an ad touchpoint (proxy = has >=1 click_id identifier).

MCP tool: tracking_identity_health

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
computedAt
string (date-time)
•
When these numbers were computed, ISO 8601 UTC. They are a live count, so this is effectively the moment of the call.
totalProfiles
integer
•
How many people the product holds in total, anonymous ones included. The denominator of both rates below.
identifiedRate
number
•
Identified people as a share of the total, normally 0 to 1 (0.42 is 42%). A drop here usually means a broken identify() call, not fewer visitors.
adTouchpointRate
number
•
People with an ad touchpoint as a share of the total, normally 0 to 1. It counts click-id identifiers, so an identifier outliving its profile can push it just above 1 — read it as an indicator, not as a proportion to assert on.
identifiedProfiles
integer
•
How many of them an email or phone is known for — the people a message can actually be sent to.
adTouchpointProfiles
integer
•
How many people arrived carrying an ad click id. A proxy for paid reach: it counts anyone with at least one click id on record.
GET/tracking/install/domains

List install-verification domains for the current product with per-domain "script seen" status, plus auto-discovered domains sending events

MCP tool: tracking_install-domains_list

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
discovered
object[]
•
Domains sending events that nobody registered — usually a staging host, a typo, or an install worth adding
registered
object[]
•
Domains deliberately put on the install checklist, each with whether its script has been seen
windowDays
number
•
Length in days of the lookback window the `seen` and `lastSeen` figures are measured over
POST/tracking/install/domains

Register a domain in the install-verification checklist for the current product

MCP tool: tracking_install-domains_create

Parameters

NameInTypeRequiredDescription
domainbody
string
•
Domain to add to the install checklist (e.g. acme.com)

Response

Returns object.

FieldTypeAlwaysDescription
domain
string
•
The domain as stored after normalisation, which may differ from what was submitted
DELETE/tracking/install/domains/:domain

Remove a domain from the install-verification checklist for the current product

MCP tool: tracking_install-domains_delete

Parameters

NameInTypeRequiredDescription
domainpath
string
•
Registered domain to remove from the checklist

Response

Returns object.

FieldTypeAlwaysDescription
ok
booleanone of: true
•
Always true — the domain was removed; a failure arrives as an error, not as false
GET/tracking/link/domains

List the cross-domain linking group (domains whose links the tracking script decorates with the visitor id) for the current product

MCP tool: tracking_link-domains_list

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
domains
string[]
•
Root domains in the linking group; the tracking script decorates links between any two of them so one visitor stays one visitor
POST/tracking/link/domains

Add a root domain to the cross-domain linking group for the current product

MCP tool: tracking_link-domains_create

Parameters

NameInTypeRequiredDescription
domainbody
string
•
Root domain to add to the cross-domain linking group (e.g. acme.io)

Response

Returns object.

FieldTypeAlwaysDescription
domain
string
•
The domain as stored after normalisation, which may differ from what was submitted
DELETE/tracking/link/domains/:domain

Remove a root domain from the cross-domain linking group for the current product

MCP tool: tracking_link-domains_delete

Parameters

NameInTypeRequiredDescription
domainpath
string
•
Root domain to remove from the cross-domain linking group

Response

Returns object.

FieldTypeAlwaysDescription
ok
booleanone of: true
•
Always true — the domain left the linking group; a failure arrives as an error, not as false
GET/tracking/live

List recent tracking events for the current product, cursor-paged for incremental polling. From the rollout, a d: anonymous id marks a cookieless one-day visitor rotating every UTC midnight, never a toolkit profile; these events appear as separate people each day in funnels, person counts and retention. Filter consent_statistics = true for consented-only figures and always for retention.

MCP tool: tracking_live-events_list

Parameters

NameInTypeRequiredDescription
sincequery
string
—
Opaque cursor from a previous response; omit for the newest events
domainquery
string
—
Filter to a single domain (e.g. acme.com)
limitquery
integer
—
Max events to return (default 50, max 200)

Response

Returns object.

FieldTypeAlwaysDescription
cursor
string | null
•
Pass back as `since` to fetch what arrived after this page. Null when there is nothing older to page into.
events
object[]
•
The page of events, newest first.
GET/tracking/profiles

List/search people (profiles) for the product; filter by email and status, cursor-paged.

MCP tool: tracking_profiles_list

Parameters

NameInTypeRequiredDescription
emailquery
string
—
Email to search people by — the whole address by default, or its beginning when emailMatch is prefix. Omit to search across everyone.
emailMatchquery
stringone of: exact, prefix
—
How the email filter is matched: exact (default) compares the whole address case-insensitively, prefix matches everyone whose address starts with what you typed.
statusquery
stringone of: anonymous, identified, customer
—
Keep only people at this stage — anonymous, identified or customer. Omit to get all three.
limitquery
integer
—
Max profiles per page (default 25, max 100)
cursorquery
string
—
Continue a previous page: pass the cursor that page returned. Omit to start from the most recently seen person.

Response

Returns object.

FieldTypeAlwaysDescription
cursor
string | null
•
Pass this back as `cursor` to fetch the next page. Null on the last page — that null is how a loop knows to stop.
profiles
object[]
•
The page of people, most recently seen first. Shorter than the requested limit on the last page.
DELETE/tracking/profiles/:profileId

GDPR erasure: permanently delete a person and their events from Postgres and record an erasure request. Archived events are flagged as a deletion gap.

MCP tool: tracking_profiles_delete

Parameters

NameInTypeRequiredDescription
profileIdpath
string (uuid)
•
The profile id (uuid)

Response

Returns object.

FieldTypeAlwaysDescription
ok
booleanone of: true
•
Always true: the response only exists when the erasure ran. A failure arrives as an error, not as ok=false.
archive
object
•
What happened to the archived copy of the events. Postgres is erased synchronously; the archive is not, and this says so out loud.
deleted
object
•
How much was actually destroyed, by kind. Worth recording: it is the evidence that the erasure did something.
profileId
string (uuid)
•
The person who was erased. Nothing else of them remains, so this is all there is left to name them by.
requestId
string (uuid)
•
This erasure attempt. The completion event carries the same value under the same name, so a step recognises its own completion even when another workflow is erasing the same person at the same moment.
recordings
object
•
What happened to the session recordings of this person. Unlike the events archive, they are deleted per person.
GET/tracking/profiles/:profileId

Get one person: profile, identity signals, and their chronological journey (query-time join over the person's anonymous ids).

MCP tool: tracking_profiles_get

Parameters

NameInTypeRequiredDescription
profileIdpath
string (uuid)
•
The profile id (uuid)
journeyCursorquery
string
—
Continue paging back through the journey: pass the cursor the previous page returned. Omit to start at the most recent event.
journeyLimitquery
integer
—
Journey events per page (default 100, max 200)

Response

Returns object.

FieldTypeAlwaysDescription
ltv
object | null
•
Lifetime value of this person, per currency. Null when revenue tracking is not in use for the product.
journey
object
•
What this person did, newest first, one page at a time. Use the export step instead when the whole history is wanted in one go.
profile
object
•
The person themselves: their handle, how far they have come, and when they were seen.
signals
object
•
Everything known about who this person is: the addresses they have been identified by, the ad clicks they arrived by, and the sites they were seen on. Every part of it is a list, and none of the lists names a primary.
acquisition
object | null
•
First touch: the campaign that brought this person in, frozen at their earliest event and never overwritten by later visits. Null for a person with no events at all.
GET/tracking/profiles/:profileId/export

Export a person as JSON: profile + identity signals + full journey (capped at 50k events; truncated flag set if exceeded).

MCP tool: tracking_profiles_export

Parameters

NameInTypeRequiredDescription
profileIdpath
string (uuid)
•
The profile id (uuid)

Response

Returns object.

FieldTypeAlwaysDescription
journey
object[]
•
The complete history, newest event first, capped at 50000 events — check `truncated` before treating it as complete.
profile
object
•
The person themselves: their handle, how far they have come, and when they were seen.
signals
object
•
Everything known about who this person is: the addresses they have been identified by, the ad clicks they arrived by, and the sites they were seen on. Every part of it is a list, and none of the lists names a primary.
truncated
boolean
•
True when the history hit the 50000-event cap and older events were left out. False means this export is everything held.
exportedAt
string (date-time)
•
When this export was produced, ISO 8601 UTC — the as-of date to put on a subject-access response.
acquisition
object | null
•
First touch: the campaign that brought this person in, frozen at their earliest event and never overwritten by later visits. Null for a person with no events at all.
GET/tracking/recording-settings

Get the session recording setting of the current product: whether recording is on, the percent of sessions recorded, the hosts whose pages are recorded, and candidate hosts to choose from. Off at 0% with no hosts until it is set; on with no hosts records nothing. Returns: { enabled, sampleRate, hosts, candidateHosts }. Fails when: the call carries no product.

MCP tool: tracking_recording-settings_get

Parameters

No parameters.

Response

Returns object.

FieldTypeAlwaysDescription
hosts
string[]
•
Exact hostnames whose pages are recorded, e.g. ["example.com", "www.example.com"]; pages on any other host are never recorded. Bare hosts only — no scheme, port, path or wildcard; www and each subdomain are separate hosts. Up to 20. Recording on with no hosts records nothing.
enabled
boolean
•
Whether session recording is on. Only visitors in full tracking mode (statistics consent, or no consent banner) are recorded.
sampleRate
integer
•
Percent of sessions recorded, 1 to 100 when on (e.g. 25); 0 is allowed only when off.
candidateHosts
string[]
•
Hosts to choose from when setting hosts: the stored hosts, the product’s install domains, then hosts its tracked pages were on in the last 30 days. A suggestion list, not a filter.
PUT/tracking/recording-settings

Turn session recording on or off for the current product, choose the hosts whose pages are recorded, and set the percent of sessions recorded (1 to 100 when on). Turning it on requires at least one host: list only the sites meant to be recorded (e.g. the marketing site, not an app or console showing customer data — page text is recorded as shown). tracking_recording-settings_get returns candidate hosts. Browsers pick the change up within about 10 minutes; the server applies it to new data within a minute. Returns: { enabled, sampleRate, hosts }. Fails when: enabled is true and hosts is missing or empty ("choose at least one host to record"); a host is not a bare hostname; more than 20 hosts; sampleRate is outside 1..100 while enabled; the call carries no product.

MCP tool: tracking_recording-settings_set

Parameters

NameInTypeRequiredDescription
enabledbody
boolean
•
Whether session recording is on. Only visitors in full tracking mode (statistics consent, or no consent banner) are recorded.
sampleRatebody
integer
•
Percent of sessions recorded, 1 to 100 when on (e.g. 25); 0 is allowed only when off.
hostsbody
string[]
—
Exact hostnames whose pages are recorded, e.g. ["example.com", "www.example.com"]; pages on any other host are never recorded. Bare hosts only — no scheme, port, path or wildcard; www and each subdomain are separate hosts. Up to 20. Recording on with no hosts records nothing. Required, at least one, when enabled is true; when turning recording off it may be left out to keep the stored list.

Response

Returns object.

FieldTypeAlwaysDescription
hosts
string[]
•
Exact hostnames whose pages are recorded, e.g. ["example.com", "www.example.com"]; pages on any other host are never recorded. Bare hosts only — no scheme, port, path or wildcard; www and each subdomain are separate hosts. Up to 20. Recording on with no hosts records nothing.
enabled
boolean
•
Whether session recording is on. Only visitors in full tracking mode (statistics consent, or no consent banner) are recorded.
sampleRate
integer
•
Percent of sessions recorded, 1 to 100 when on (e.g. 25); 0 is allowed only when off.
GET/tracking/recordings

List session recordings of the current product, newest first: who (profile), how they arrived (entry page, utm, ad click), device, length, and whether the session converted. Filter by period (default the last 30 days), person, visitor, device, campaign, source, entry page, conversion and minimum length; cursor-paged. Device, campaign, source and conversion select the same recordings as tracking_heatmaps_get with the same filters. Returns: { items, nextCursor }. Fails when: cursor is not one this tool issued; the call carries no product.

MCP tool: tracking_recordings_list

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Start of the period, ISO 8601 (e.g. 2026-10-01T00:00:00Z): recordings that started at or after it. Default: 30 days before `to`, the whole retention window.
toquery
string (date-time)
—
End of the period, ISO 8601: recordings that started at or before it. Default: now.
profileIdquery
string (uuid)
—
Only this person: every browser they were seen on, merged profiles included.
anonymousIdquery
string
—
Only this visitor id (one browser).
utmCampaignquery
string
—
Only recordings whose entry page carried this utm_campaign, e.g. spring.
utmSourcequery
string
—
Only recordings whose entry page carried this utm_source, e.g. google.
devicequery
stringone of: desktop, tablet, mobile
—
Only recordings from this kind of device, as classified on ingest: desktop, tablet or mobile.
entryUrlContainsquery
string
—
Only recordings whose entry page URL contains this text, case-insensitively, e.g. /pricing.
convertedquery
boolean
—
true: only sessions with a conversion or a payment; false: only sessions without one. Omit for both.
minDurationMsquery
integer
—
Only recordings at least this long, in milliseconds, e.g. 30000.
cursorquery
string
—
Continue a previous page: pass the nextCursor it returned. Omit to start from the newest recording.
limitquery
integer
—
Recordings per page, 1 to 100 (default 50).

Response

Returns object.

FieldTypeAlwaysDescription
items
object[]
•
Newest first.
nextCursor
string | null
•
Pass back as cursor for the next page. Null on the last page.
GET/tracking/recordings/:id

Get one session recording: its summary, its segments (page loads, in play order) and the tracker events of the recording itself (its hosts, its time span) with their offset on the player clock, for a timeline, and the first conversion of the session after the recording. Returns: the summary plus { clockOffsetMs, segments, events, eventsTruncated, laterConversion }. Fails when: no recording with that id is visible in this product.

MCP tool: tracking_recordings_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The recording id (uuid), from tracking_recordings_list.

Response

Returns object.

FieldTypeAlwaysDescription
id
string (uuid)
•
The recording id. Pass it to tracking_recordings_get.
device
string | null
•
desktop, mobile or tablet, from the browser. Null when unknown.
events
object[]
•
Tracker events of the recording itself — pages on the recording's hosts, from 5 s before its start to 5 s after its end — oldest first, at most 2000.
status
stringone of: active, closed
•
active: the session may still be recording; closed: finished (4 h cap).
entryUrl
string | null
•
The first page recorded. Personal data: a URL can carry an email. Null when unknown.
segments
object[]
•
In start order — the order to play them in.
viewport
object
•
Browser viewport at the start of the recording.
converted
boolean
•
True when the same session has an event marked as a conversion or a signup, trial, subscription or payment.
profileId
string (uuid) | null
•
The person behind the visitor, resolved now, so a later merge is honoured. Null for a visitor never tied to a profile.
startedAt
string (date-time)
•
When the recording started, ISO 8601 UTC, on the server clock.
utmMedium
string | null
•
utm_medium of the entry page. Null when untagged.
utmSource
string | null
•
utm_source of the entry page. Null when untagged.
durationMs
integer
•
Length of the recording in milliseconds.
clickIdType
string | null
•
Ad network of the click that opened the session: gclid for Google Ads, fbclid for Meta. Null for a non-ad arrival.
utmCampaign
string | null
•
utm_campaign of the entry page. Null when untagged.
segmentCount
integer
•
Page loads (and consent re-starts) recorded in the session.
clockOffsetMs
integer
•
Server clock minus browser clock, measured on the first slice. rrweb timestamps and `events[].at` are on the browser clock.
eventsTruncated
boolean
•
True when the recording had more than 2000 events and the rest were left out.
laterConversion
object | null
•
The first conversion of the same session that is not in events: after the recording ended (up to 24 h later), or during it on a host the recording has no page of. Any host. Compare at with the span of the recording to tell which. Null when there is none.
GET/tracking/recordings/:id/chunks

Get the rrweb events of one segment of a recording for playback, one page at a time (about 2 MiB of events by default); follow nextSeq until it is null. Lost or undecodable stretches are reported in gaps, never as an error. Returns: { events, gaps, nextSeq }. Fails when: the recording is not visible in this product or has no such segment.

MCP tool: tracking_recordings_chunks_get

Parameters

NameInTypeRequiredDescription
idpath
string (uuid)
•
The recording id (uuid), from tracking_recordings_list.
pidquery
string
•
Page load of the segment, from the segments of tracking_recordings_get.
segquery
integer
•
Consent (re)start of the segment within that page load, from tracking_recordings_get.
fromSeqquery
integer
—
Continue a segment: pass the nextSeq the previous page returned. Default 0, the start.
maxBytesquery
integer
—
Decoded bytes per page (default 2097152, max 8388608). A page ends at the first whole payload past it and always holds at least one.

Response

Returns object.

FieldTypeAlwaysDescription
gaps
object[]
•
Stretches of the segment that could not be played: lost slices, or payloads that did not decode. Show "part of the recording is lost" there.
events
array
•
rrweb events of this page of the segment, in order. Feed them to the player.
nextSeq
integer | null
•
Pass back as fromSeq for the next page. Null once the segment is read to its end. On an active recording it can equal the fromSeq you sent, with no events: the last part is still arriving — ask again later.
GET/tracking/reports/attributed-journey/:profileId

One person's journey with, for their originating conversion, the attribution decision explained (winning touchpoint + why) under the requested model and lookback window. Attribution is never locked in — changing model/window re-reads the same history.

MCP tool: tracking_reports_attributed_journey

Parameters

NameInTypeRequiredDescription
profileIdpath
string (uuid)
•
The profile id (uuid)
modelquery
stringone of: last_click, first_click
—
Attribution model to explain the decision under; re-reads the same history, so switching it is free (default 'last_click').
lookbackDaysquery
integer
—
How far back before the conversion a touchpoint may be credited, in days (default 30).
fromquery
string (date-time)
—
Show only journey events at or after this instant (ISO). Omit for the whole history.
toquery
string (date-time)
—
Show only journey events at or before this instant (ISO). Omit for the whole history.

Response

Returns object.

FieldTypeAlwaysDescription
journey
object
•
What this person actually did, in order.
decisions
object[]
•
Holds at most one entry: the decision for this person's originating conversion, present only when that conversion falls inside the requested window. Kept as a list for callers that already read it; `originatingDecision` is the same value at a bindable path.
profileId
string
•
The person this journey belongs to, echoed back from the request.
originatingDecision
object | null
•
The attribution decision for this person's originating conversion — the same value as `decisions[0]`, at a path a workflow can bind. Null means the decision is not in THIS window, not that the person never converted: a conversion before `from` or after `to` is excluded here while still being their originating one. Widen the window to see it.
GET/tracking/reports/event-volume

Traffic for a date range as TWO headline figures plus a data-quality block. totalEvents counts events. visitorsDeduplicatedPerUtcDay counts PEOPLE, over both populations at once: consenting and no-banner visitors by anonymous_id, cookieless visitors by server-derived daily_visitor_key. It is one COUNT DISTINCT, not a sum of two figures, and there is no second set of numbers to add to it. READ THE FIELD NAME LITERALLY — the daily key rotates every UTC midnight, so a returning cookieless visitor is counted again. From the rollout, that key also appears as anonymous_id = d:<daily key> on the event: a one-day graph person, never a toolkit profile. These visitors enter funnels, person counts and retention as separate people each day. Weekly and monthly uniques are OVERSTATED for this traffic; filter consent_statistics = true for consented-only figures and always for retention, returning-visitor, frequency and loyalty analysis. dataQuality.visitorsOverstated tells you whether the over-count applies to this window, and dataQuality.utcDaysInRange gives its UTC-day span. dataQuality describes how COMPLETE the two headline figures are and contains no metric of its own — never present anything inside it as a headline number and never add it to anything. cookielessShare and noBannerShare are the fractions of events from cookieless visitors and from sites with no banner. consentGrantedEvents + cookielessEvents + noBannerEvents = totalEvents. noBannerEvents (nobody was ever asked) stays distinct from cookielessEvents (denied or undecided). identifiedEvents counts only non-cookieless events carrying an anonymous_id, excluding d: rows; never add it to the consent buckets.

MCP tool: tracking_reports_event_volume

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Start of the range to count, inclusive (ISO 8601). Optional — defaults to 30 days back, the start of that UTC day.
toquery
string (date-time)
—
End of the range to count, inclusive (ISO 8601). Optional — defaults to the moment of the call.
domainquery
string
—
Count only this site. Omit to count every site the product sends from.

Response

Returns object.

FieldTypeAlwaysDescription
to
string (date-time)
•
End of the range the figures cover, echoed back (ISO 8601, UTC).
from
string (date-time)
•
Start of the range the figures cover, echoed back (ISO 8601, UTC).
domain
string | null
•
Site the figures were restricted to; null when every site of the product is included.
computedAt
string (date-time)
•
When this report was computed (ISO 8601, UTC).
dataQuality
object
•
How COMPLETE the two headline figures above are. Contains no metric of its own — never present a field of it as a headline number and never add it to anything. consentGrantedEvents + cookielessEvents + noBannerEvents = totalEvents.
totalEvents
number
•
How many events arrived in the range, across every consent state.
visitorsDeduplicatedPerUtcDay
number
•
How many PEOPLE those events came from: one COUNT DISTINCT over consenting visitors (by anonymous id) and declining visitors (by a daily key destroyed each UTC midnight) at once. Over a range longer than one UTC day this is an OVER-count of the declining half — read `dataQuality.visitorsOverstated` before reporting it.
GET/tracking/reports/revenue-by-source

Revenue attributed by channel + UTM breakdown for a date range, under a chosen attribution model and lookback window. Includes a distinct unattributed row, totals, and a count-based match rate. Revenue is per-currency (never summed across currencies); refunds are netted explicitly.

MCP tool: tracking_reports_revenue_by_source

Parameters

NameInTypeRequiredDescription
fromquery
string (date-time)
—
Cohort window start (ISO); selects conversions by subscription start. Optional — defaults to 30 days back, the start of that UTC day.
toquery
string (date-time)
—
Cohort window end (ISO). Optional — defaults to the moment of the call.
modelquery
stringone of: last_click, first_click
—
Attribution model
lookbackDaysquery
integer
—
Lookback window in days (default 30)
domainquery
string
—
Only consider touchpoints on this domain

Response

Returns object.

FieldTypeAlwaysDescription
to
string (date-time)
•
End of the cohort window the figures cover, echoed back (ISO 8601, UTC).
from
string (date-time)
•
Start of the cohort window the figures cover, echoed back (ISO 8601, UTC).
model
stringone of: last_click, first_click
•
Attribution model the credit was assigned under, echoed back. Pass the same value to `tracking_reports_source_people` to drill into a row.
domain
string | null
•
Site touchpoints were restricted to; null when every site of the product was considered.
totals
object
•
Every channel plus `unattributed`. This is the whole window, not the attributed part of it.
channels
object[]
•
One row per channel that earned revenue in the window. Channels with none are omitted.
matchRate
number
•
Fraction of paying people (0..1) a touchpoint could be found for: attributed customers over `totals.customers`. Count-based, never revenue-weighted.
computedAt
string (date-time)
•
When this report was computed (ISO 8601, UTC).
lookbackDays
number
•
How far back before a conversion a touchpoint was allowed to be credited, in days; echoed back.
unattributed
object
•
Revenue that reached no channel — kept as its own row so the channel rows are never quietly inflated to cover it.
GET/tracking/reports/source-people

List the people (profiles) behind one channel / UTM row from the revenue-by-source report, under the same model + window. Keyset-paginated; each person carries their attributed lifetime revenue per currency.

MCP tool: tracking_reports_source_people

Parameters

NameInTypeRequiredDescription
channelquery
stringone of: paid, organic, direct, email
•
Channel to drill into
utmSourcequery
string
—
utm_source of the breakdown row to drill into. Omit for no filter; to match the IS-NULL row, list it in utmNulls instead.
utmMediumquery
string
—
utm_medium of the breakdown row to drill into. Omit for no filter; to match the IS-NULL row, list it in utmNulls instead.
utmCampaignquery
string
—
utm_campaign of the breakdown row to drill into. Omit for no filter; to match the IS-NULL row, list it in utmNulls instead.
clickIdTypequery
string
—
Native click-id type of the breakdown row to drill into (e.g. 'gclid'). Tri-state: omit for no filter (all click ids), pass a value to match it, or list 'clickIdType' in utmNulls to match the IS-NULL row.
utmNullsquery
string
—
Comma-separated dimension names (utmSource,utmMedium,utmCampaign,clickIdType) that must be IS NULL
modelquery
stringone of: last_click, first_click
—
Attribution model to credit the touchpoint under; must match the report this row came from (default 'last_click').
lookbackDaysquery
integer
—
How far back before a conversion a touchpoint may be credited, in days; must match the report this row came from (default 30).
fromquery
string (date-time)
—
Cohort window start (ISO); must match the report this row came from. Optional — defaults to 30 days back, the start of that UTC day.
toquery
string (date-time)
—
Cohort window end (ISO); must match the report this row came from. Optional — defaults to the moment of the call.
domainquery
string
—
Only consider touchpoints on this domain; must match the report this row came from. Omit for no restriction.
cursorquery
string
—
Opaque keyset cursor from a previous page
limitquery
integer
—
People per page (default 50, max 200)

Response

Returns object.

FieldTypeAlwaysDescription
cursor
string | null
•
Pass back as `cursor` for the next page. Null on the last page.
people
object[]
•
The page of people behind the requested row, ordered by the keyset the cursor walks.
GET/tracking/snippet

Get the tracking snippet for the caller's current product. Install it unconditionally. Do NOT wrap it in a consent gate and do NOT load it only after consent is granted: the tracker reads the visitor consent decision itself and switches to a cookieless mode that writes no cookies and sends no identifiers when statistics consent is declined or not yet given. Gating this tag makes declining and undecided visitors invisible entirely — the failure this behaviour exists to prevent. Set consentBanner: true when the page runs the Lepsto consent banner. Without it, a tracker that loads before the banner sees no consent API yet and can write cookies before the visitor decides. Do NOT set it on a page without the banner: the tracker would then wait for a decision that never comes and stay cookieless for every visitor.

MCP tool: tracking_snippets_get

Parameters

NameInTypeRequiredDescription
consentBannerquery
boolean
—
true when the page runs the Lepsto consent banner: both snippets then carry data-consent="banner", and the tracker stays cookieless until the banner reports a decision. Default false.

Response

Returns object.

FieldTypeAlwaysDescription
host
string
•
Tracking host the snippet sends to — the customer-facing domain events and the bundle are served from.
snippet
string
•
The tag to paste into every page, verbatim, before </head>. Includes the consent-aware bootstrap; install it unconditionally rather than behind a consent gate.
scriptUrl
string
•
Absolute URL of the tracker bundle the snippet loads; already points at this product's own tracking host.
minimalSnippet
string
•
The same tag stripped to the bare script element, for tag managers and CMS fields that reject anything else. Behaves identically; use it only when the full snippet will not fit.
Was this page helpful?
Esc

Start typing to search the docs.

↑↓navigate↵select