REST API
The Tracking area publishes 36 REST endpoints. Paths are relative to https://api.lessly.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
| Name | In | Type | Required | Description |
|---|
| status | query | string | — | Filter by status; omit for all |
| search | query | string | — | Case-insensitive substring match on the event name |
| sort | query | string | — | Sort column (default count) |
| order | query | string | — | Sort direction (default desc) |
Response
| Field | Type | Always | Description |
|---|
| names | array | • | — |
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
| Name | In | Type | Required | Description |
|---|
| name | body | string | • | The event name to archive/unarchive |
Response
| Field | Type | Always | Description |
|---|
| name | string | • | — |
| status | string | • | — |
POST/tracking/catalog/unarchive
Unarchive an event name (restores its visibility in dashboards).
MCP tool: tracking_event-names_unarchive
Parameters
| Name | In | Type | Required | Description |
|---|
| name | body | string | • | The event name to archive/unarchive |
Response
| Field | Type | Always | Description |
|---|
| name | string | • | — |
| status | string | • | — |
GET/tracking/domains
List the product's custom domains and tracking-host bindings
MCP tool: tracking_domains_list
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| domains | array | • | — |
| bindings | array | • | — |
POST/tracking/domains
Claim a first-party tracking host under a product domain
MCP tool: tracking_domains_create
Parameters
| Name | In | Type | Required | Description |
|---|
| domainId | body | string | • | — |
| host | body | string | — | — |
| records | body | array | — | — |
Response
| Field | Type | Always | Description |
|---|
| binding | object | • | — |
| instructions | array | • | — |
DELETE/tracking/domains/:bindingId
Release a tracking-host binding
MCP tool: tracking_domains_delete
Parameters
| Name | In | Type | Required | Description |
|---|
| bindingId | path | string | • | — |
Response
| Field | Type | Always | Description |
|---|
| ok | boolean | • | — |
GET/tracking/domains/:bindingId
Get one tracking-host binding and its status
MCP tool: tracking_domains_get
Parameters
| Name | In | Type | Required | Description |
|---|
| bindingId | path | string | • | — |
Response
| Field | Type | Always | Description |
|---|
| host | string | • | — |
| status | string | • | — |
| records | array | • | — |
| domainId | string | • | — |
| bindingId | string | • | — |
| createdAt | string | • | — |
| productId | string | • | — |
| updatedAt | string | • | — |
| statusDetail | string | • | — |
| ownerExtension | string | • | — |
POST/tracking/domains/:bindingId/verify
Run an immediate liveness check for a pending binding
MCP tool: tracking_domains_verify
Parameters
| Name | In | Type | Required | Description |
|---|
| bindingId | path | string | • | — |
Response
| Field | Type | Always | Description |
|---|
| host | string | • | — |
| status | string | • | — |
| records | array | • | — |
| domainId | string | • | — |
| bindingId | string | • | — |
| createdAt | string | • | — |
| productId | string | • | — |
| updatedAt | string | • | — |
| statusDetail | string | • | — |
| ownerExtension | string | • | — |
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.
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
| Field | Type | Always | Description |
|---|
| mode | string | • | — |
| rules | array | • | — |
| enabled | boolean | • | — |
| productId | string | • | — |
| lookbackDays | number | • | — |
| accountCurrency | string | • | — |
| dynamicValueEvents | array | • | — |
| enhancedConversions | boolean | • | — |
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
| Name | In | Type | Required | Description |
|---|
| enabled | body | boolean | — | Master switch for conversion feedback (default off) |
| mode | body | string | — | existing_pixel = fill gaps; fresh_pixel = our data only |
| lookbackDays | body | integer | — | Click lookback window for gclid match (<=90) |
| rules | body | array | — | Map a tracked event to a Google conversion action with a per-rule value (net revenue or a fixed amount) |
| enhancedConversions | body | boolean | — | Enhanced conversions: also send hashed email/phone as additive match keys alongside gclid (default off) |
Response
| Field | Type | Always | Description |
|---|
| config | object | • | — |
| guidance | array | • | — |
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.
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
| Field | Type | Always | Description |
|---|
| failed | number | • | — |
| matched | number | • | — |
| noGclid | number | • | — |
| skipped | string | — | — |
| selected | number | • | — |
| uploaded | number | • | — |
| productId | string | • | — |
| zeroValue | number | • | — |
| partialFailureError | string | — | — |
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
| Field | Type | Always | Description |
|---|
| mode | string | • | — |
| failed | number | • | — |
| enabled | boolean | • | — |
| lastRun | object | • | — |
| guidance | array | • | — |
| uploaded | number | • | — |
| ruleCount | number | • | — |
| lookbackDays | number | • | — |
| accountCurrency | string | • | — |
| dynamicValueEvents | array | • | — |
| enhancedConversions | boolean | • | — |
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
| Name | In | Type | Required | Description |
|---|
| limit | query | integer | — | — |
GET/tracking/googleads/reports/roas
Google Ads ROAS/CPA per campaign->ad_group->ad joining frozen cost rollups with attributed revenue. Attributed ROAS/CPA at campaign level; cost + platform metrics at every level. Currency-isolated; never summed across currencies. Query: from,to (ISO, required), model (last_click|first_click), lookbackDays (1-365), domain?, customerId?.
MCP tool: tracking_googleads_roas_report
Parameters
| Name | In | Type | Required | Description |
|---|
| from | query | string | • | — |
| to | query | string | • | — |
| model | query | string | — | — |
| lookbackDays | query | integer | — | — |
| domain | query | string | — | — |
| customerId | query | string | — | — |
Response
| Field | Type | Always | Description |
|---|
| to | string | • | — |
| from | string | • | — |
| model | string | • | — |
| domain | string | • | — |
| accounts | array | • | — |
| computedAt | string | • | — |
| lookbackDays | number | • | — |
| unmatchedAttributed | array | • | — |
GET/tracking/googleads/reports/us-vs-platform
Per-campaign comparison: our attributed revenue/conversions vs Google-reported conversions and conversions_value, within each account currency. Query: from,to (ISO, required), model, lookbackDays, domain?, customerId?.
MCP tool: tracking_googleads_us_vs_platform
Parameters
| Name | In | Type | Required | Description |
|---|
| from | query | string | • | — |
| to | query | string | • | — |
| model | query | string | — | — |
| lookbackDays | query | integer | — | — |
| domain | query | string | — | — |
| customerId | query | string | — | — |
Response
| Field | Type | Always | Description |
|---|
| to | string | • | — |
| from | string | • | — |
| model | string | • | — |
| domain | string | • | — |
| accounts | array | • | — |
| computedAt | string | • | — |
| lookbackDays | number | • | — |
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
| Field | Type | Always | Description |
|---|
| rows | object | • | — |
| reason | string | — | — |
| status | string | • | — |
| window | object | • | — |
| lastSyncedAt | string | • | — |
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
| Name | In | Type | Required | Description |
|---|
| from | query | string | — | Range start (ISO); defaults to 30 days ago |
| to | query | string | — | Range end (ISO); defaults to now |
Response
| Field | Type | Always | Description |
|---|
| to | string | • | — |
| from | string | • | — |
| installed | boolean | • | — |
| truncated | boolean | • | — |
| paidClicks | number | • | — |
| dataQuality | object | • | — |
| breakageRate | number | • | — |
| taggedClicks | number | • | — |
| lastUntaggedAt | string | • | — |
| untaggedClicks | number | • | — |
| firstUntaggedAt | string | • | — |
| sampleUntaggedUrls | array | • | — |
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
| Field | Type | Always | Description |
|---|
| computedAt | string | • | — |
| totalProfiles | number | • | — |
| identifiedRate | number | • | — |
| adTouchpointRate | number | • | — |
| identifiedProfiles | number | • | — |
| adTouchpointProfiles | number | • | — |
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
| Field | Type | Always | Description |
|---|
| discovered | array | • | — |
| registered | array | • | — |
| windowDays | number | • | — |
POST/tracking/install/domains
Register a domain in the install-verification checklist for the current product
MCP tool: tracking_install-domains_create
Parameters
| Name | In | Type | Required | Description |
|---|
| domain | body | string | • | Domain to add to the install checklist (e.g. acme.com) |
Response
| Field | Type | Always | Description |
|---|
| domain | string | • | — |
DELETE/tracking/install/domains/:domain
Remove a domain from the install-verification checklist for the current product
MCP tool: tracking_install-domains_delete
Parameters
| Name | In | Type | Required | Description |
|---|
| domain | path | string | • | Registered domain to remove from the checklist |
Response
| Field | Type | Always | Description |
|---|
| ok | boolean | • | — |
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
| Field | Type | Always | Description |
|---|
| domains | array | • | — |
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
| Name | In | Type | Required | Description |
|---|
| domain | body | string | • | Root domain to add to the cross-domain linking group (e.g. acme.io) |
Response
| Field | Type | Always | Description |
|---|
| domain | string | • | — |
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
| Name | In | Type | Required | Description |
|---|
| domain | path | string | • | Root domain to remove from the cross-domain linking group |
Response
| Field | Type | Always | Description |
|---|
| ok | boolean | • | — |
GET/tracking/live
List the most recent tracking events for the current product (live visitor stream). Cursor-paged for incremental polling.
MCP tool: tracking_live-events_list
Parameters
| Name | In | Type | Required | Description |
|---|
| since | query | string | — | Opaque cursor from a previous response; omit for the newest events |
| domain | query | string | — | Filter to a single domain (e.g. acme.com) |
| limit | query | integer | — | Max events to return (default 50, max 200) |
Response
| Field | Type | Always | Description |
|---|
| cursor | string | • | — |
| events | array | • | — |
GET/tracking/profiles
List/search people (profiles) for the product; filter by email and status, cursor-paged.
MCP tool: tracking_profiles_list
Parameters
| Name | In | Type | Required | Description |
|---|
| email | query | string | — | Exact email to find (case-insensitive), or a prefix when emailMatch=prefix |
| emailMatch | query | string | — | How to match the email filter |
| status | query | string | — | Filter by profile status |
| limit | query | integer | — | Max profiles per page (default 25, max 100) |
| cursor | query | string | — | Opaque pagination cursor from a previous response |
Response
| Field | Type | Always | Description |
|---|
| cursor | string | • | — |
| profiles | array | • | — |
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
| Name | In | Type | Required | Description |
|---|
| profileId | path | string | • | The profile id (uuid) |
Response
| Field | Type | Always | Description |
|---|
| ok | boolean | • | — |
| archive | object | • | — |
| deleted | object | • | — |
| profileId | string | • | — |
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
| Name | In | Type | Required | Description |
|---|
| profileId | path | string | • | The profile id (uuid) |
| journeyCursor | query | string | — | Opaque cursor to page further back through the journey |
| journeyLimit | query | integer | — | Journey events per page (default 100, max 200) |
Response
| Field | Type | Always | Description |
|---|
| ltv | object | • | — |
| journey | object | • | — |
| profile | object | • | — |
| signals | object | • | — |
| acquisition | object | • | — |
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
| Name | In | Type | Required | Description |
|---|
| profileId | path | string | • | The profile id (uuid) |
Response
| Field | Type | Always | Description |
|---|
| journey | array | • | — |
| profile | object | • | — |
| signals | object | • | — |
| truncated | boolean | • | — |
| exportedAt | string | • | — |
| acquisition | object | • | — |
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
| Name | In | Type | Required | Description |
|---|
| profileId | path | string | • | The profile id (uuid) |
| model | query | string | — | — |
| lookbackDays | query | integer | — | — |
| from | query | string | — | — |
| to | query | string | — | — |
Response
| Field | Type | Always | Description |
|---|
| journey | object | • | — |
| decisions | array | • | — |
| profileId | string | • | — |
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: visitors who consented are deduplicated by their anonymous_id, visitors who declined by a 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 caveat is the metric, not a footnote. The daily key is rebuilt from a salt that is destroyed every UTC midnight, so the same declining visitor gets a DIFFERENT key tomorrow and is counted again. Consequences you must state whenever you report this number over more than one day: (1) weekly and monthly unique-visitor counts are OVERSTATED, and the longer the window the worse it gets — a visitor who comes back on ten days counts as ten people; (2) returning-visitor, retention, frequency and loyalty analysis DO NOT WORK on this traffic at all, because the identity that would link the days was never created. This is not a defect awaiting a fix and no post-processing recovers the real figure; Plausible, PostHog and Matomo concede the same limitation about their own daily keys. dataQuality.visitorsOverstated tells you whether it bites for the window you asked for (true when the range spans more than one UTC day and there is declining traffic in it), and dataQuality.utcDaysInRange is how many UTC days the range spans. For an exact people count, ask for a single UTC day. 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 that arrived from declining visitors and from sites running no consent banner. consentGrantedEvents + cookielessEvents + noBannerEvents = totalEvents. noBannerEvents (nobody was ever asked) is deliberately kept apart from cookielessEvents (the visitor declined); merging them would tell a customer people refused when nobody was asked. identifiedEvents is a DIFFERENT cut — events carrying an anonymous_id — that overlaps the consent buckets and is NOT the complement of cookielessEvents; never add those two together.
MCP tool: tracking_reports_event_volume
Parameters
| Name | In | Type | Required | Description |
|---|
| from | query | string | • | — |
| to | query | string | • | — |
| domain | query | string | — | — |
Response
| Field | Type | Always | Description |
|---|
| to | string | • | — |
| from | string | • | — |
| domain | string | • | — |
| computedAt | string | • | — |
| dataQuality | object | • | — |
| totalEvents | number | • | — |
| visitorsDeduplicatedPerUtcDay | number | • | — |
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
| Name | In | Type | Required | Description |
|---|
| from | query | string | • | Cohort window start (ISO); selects conversions by subscription start |
| to | query | string | • | Cohort window end (ISO) |
| model | query | string | — | Attribution model |
| lookbackDays | query | integer | — | Lookback window in days (default 30) |
| domain | query | string | — | Only consider touchpoints on this domain |
Response
| Field | Type | Always | Description |
|---|
| to | string | • | — |
| from | string | • | — |
| model | string | • | — |
| domain | string | • | — |
| totals | object | • | — |
| channels | array | • | — |
| matchRate | number | • | — |
| computedAt | string | • | — |
| lookbackDays | number | • | — |
| unattributed | object | • | — |
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
| Name | In | Type | Required | Description |
|---|
| channel | query | string | • | Channel to drill into |
| utmSource | query | string | — | — |
| utmMedium | query | string | — | — |
| utmCampaign | query | string | — | — |
| clickIdType | query | 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. |
| utmNulls | query | string | — | Comma-separated dimension names (utmSource,utmMedium,utmCampaign,clickIdType) that must be IS NULL |
| model | query | string | — | — |
| lookbackDays | query | integer | — | — |
| from | query | string | • | — |
| to | query | string | • | — |
| domain | query | string | — | — |
| cursor | query | string | — | Opaque keyset cursor from a previous page |
| limit | query | integer | — | People per page (default 50, max 200) |
Response
| Field | Type | Always | Description |
|---|
| cursor | string | • | — |
| people | array | • | — |
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.
MCP tool: tracking_snippets_get
Parameters
No parameters.
Response
| Field | Type | Always | Description |
|---|
| host | string | • | — |
| snippet | string | • | — |
| scriptUrl | string | • | — |
| minimalSnippet | string | • | — |
Was this page helpful?Thanks for your feedback!