The Analytics area publishes 18 REST endpoints. Paths are relative to https://api.lessly.com; see Authentication for the required header.
GET/analytics/catalog
Read the analytics semantic catalog: every entity this product may chart, with its declared metrics, dimensions and person-graph identity kinds. Call this FIRST to discover the exact `entity`, `metric` and `dimension` names analytics_metric_query and analytics_funnel_run accept — those names are resolved against this catalog and a name that is not in it is rejected.
MCP tool: analytics_catalog_get
Parameters
No parameters.
Response
Returns object.
| Field | Type | Always | Description |
|---|
cycle | object | null | • | — |
entities | object[] | • | — |
product_id | string | • | — |
generated_at | string | • | — |
GET/analytics/dashboards
List the saved dashboards of the current product, newest first. Narrow by an exact tag or by a case-insensitive substring of the name or slug. Returns definitions, not results.
MCP tool: analytics_dashboard_list
Parameters
| Name | In | Type | Required | Description |
|---|
tag | query | string | — | Exact tag the dashboard must carry |
q | query | string | — | Case-insensitive substring of the name or slug |
Response
Returns object.
| Field | Type | Always | Description |
|---|
dashboards | object[] | • | — |
POST/analytics/dashboards
Save a named dashboard for the current product: up to forty tiles, each either a reference to a saved insight by its uuid (from analytics_insight_list) or a block of markdown, each placed on a twelve-column grid. The slug is the address the dashboard is read by and cannot be changed later. Stores the arrangement only; it does not run it. Every insight a tile names must already exist in this product, so a stored dashboard always resolves.
MCP tool: analytics_dashboard_create
Parameters
| Name | In | Type | Required | Description |
|---|
slug | body | string | • | — |
name | body | string | • | — |
tiles | body | object[] | • | — |
tags | body | string[] | — | — |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
tiles | object[] | • | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
DELETE/analytics/dashboards/:id
Permanently delete one saved dashboard of the current product. The insights its tiles referred to are not deleted.
MCP tool: analytics_dashboard_delete
Parameters
| Name | In | Type | Required | Description |
|---|
id | path | string (uuid) | • | The dashboard's uuid; slugs are not accepted here |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
deleted | booleanone of: true | • | — |
PATCH/analytics/dashboards/:id
Change fields of a saved dashboard of the current product. Only the fields supplied are changed; the rest keep their stored values. Supplying tiles replaces the whole arrangement, so send the tiles you want to keep along with the new ones. The slug cannot be changed — create a new dashboard instead.
MCP tool: analytics_dashboard_update
Parameters
| Name | In | Type | Required | Description |
|---|
name | body | string | — | — |
tiles | body | object[] | — | — |
tags | body | string[] | — | — |
id | path | string (uuid) | • | The dashboard's uuid; slugs are not accepted here |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
tiles | object[] | • | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
GET/analytics/dashboards/:idOrSlug
Read one saved dashboard of the current product by its slug or its id. Returns the tiles and their layout, not results.
MCP tool: analytics_dashboard_get
Parameters
| Name | In | Type | Required | Description |
|---|
idOrSlug | path | string | • | The dashboard's slug, or its uuid |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
tiles | object[] | • | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
POST/analytics/dashboards/:idOrSlug/run
Run every tile of a saved dashboard of the current product and return one entry per tile, in board order: the tile itself, and what it produced. An insight tile carries exactly what analytics_insight_run answers for that insight; a text tile carries a null result, because its content is the tile. `from` and `to` override the window of every insight tile for this call only, changing nothing stored. A tile that fails carries an error with an HTTP status and does not stop the rest of the board, so check each tile's result before reading numbers.
MCP tool: analytics_dashboard_run
Parameters
| Name | In | Type | Required | Description |
|---|
from | body | string (date-time) | — | Inclusive window start; overrides the stored window |
to | body | string (date-time) | — | Inclusive window end; overrides the stored window |
idOrSlug | path | string | • | The dashboard's slug, or its uuid |
Response
Returns object.
| Field | Type | Always | Description |
|---|
tiles | object[] | • | — |
dashboard | object | • | — |
POST/analytics/funnels/run
Run an ordered conversion funnel over the analytics semantic layer for the current product. Each step names a semantic entity (optionally narrowed by declared-dimension filters) and is counted in resolved persons from the identity graph, so a person is counted once per step no matter how many rows or identifiers they produced. Deterministic: entity, dimension and metric names are resolved against the semantic catalog, never generated. A step whose entity has a `propertiesColumn` in the catalog may also filter on `props.<key>`, compared as a string. Prefer this over analytics_query_run whenever the question is a conversion between ordered steps.
MCP tool: analytics_funnel_run
Parameters
| Name | In | Type | Required | Description |
|---|
steps | body | object[] | • | Ordered funnel steps, 2 to 5 |
from | body | string | • | Inclusive first day (UTC) |
to | body | string | • | Inclusive last day (UTC) |
window_days | body | integer | — | Maximum days between two CONSECUTIVE steps for the later one to count |
grain | body | stringone of: day, week, month | — | When set, also return per-step persons bucketed by step-entry time |
Response
Returns object.
| Field | Type | Always | Description |
|---|
meta | object | • | — |
steps | object[] | • | — |
series | object[] | — | — |
GET/analytics/insights
List the saved insights of the current product, newest first. Narrow by an exact tag or by a case-insensitive substring of the name or slug. Returns definitions, not results.
MCP tool: analytics_insight_list
Parameters
| Name | In | Type | Required | Description |
|---|
tag | query | string | — | Exact tag the insight must carry |
q | query | string | — | Case-insensitive substring of the name or slug |
Response
Returns object.
| Field | Type | Always | Description |
|---|
insights | object[] | • | — |
POST/analytics/insights
Save a named insight for the current product: one to eight series over the analytics semantic layer, an optional formula combining them by key, a time window and how to display it. The slug is the address the insight is read by and cannot be changed later. Stores the definition only; it does not run it. Series requests are validated with the same schemas analytics_metric_query and analytics_funnel_run accept, so a stored insight always runs.
MCP tool: analytics_insight_create
Parameters
| Name | In | Type | Required | Description |
|---|
slug | body | string | • | — |
name | body | string | • | — |
description | body | string | — | — |
kind | body | stringone of: trend, funnel, number, retention | • | — |
series | body | object[] | • | — |
formula | body | string | null | — | — |
window | body | object | • | — |
grain | body | stringone of: day, week, month | — | — |
display | body | stringone of: line, bar, bold_number, table | — | — |
tags | body | string[] | — | — |
target | body | object | null | — | — |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
kind | stringone of: trend, funnel, number, retention | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
grain | stringone of: day, week, month | — | — |
series | object[] | • | — |
target | object | null | — | — |
window | object | • | — |
display | stringone of: line, bar, bold_number, table | — | — |
formula | string | null | — | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
description | string | — | — |
DELETE/analytics/insights/:id
Permanently delete one saved insight of the current product. Dashboards referring to it will no longer resolve it.
MCP tool: analytics_insight_delete
Parameters
| Name | In | Type | Required | Description |
|---|
id | path | string (uuid) | • | The insight's uuid; slugs are not accepted here |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
deleted | booleanone of: true | • | — |
PATCH/analytics/insights/:id
Change fields of a saved insight of the current product. Only the fields supplied are changed; the rest keep their stored values. The slug cannot be changed — create a new insight instead.
MCP tool: analytics_insight_update
Parameters
| Name | In | Type | Required | Description |
|---|
name | body | string | — | — |
description | body | string | — | — |
kind | body | stringone of: trend, funnel, number, retention | — | — |
series | body | object[] | — | — |
formula | body | string | null | — | — |
window | body | object | — | — |
grain | body | stringone of: day, week, month | — | — |
display | body | stringone of: line, bar, bold_number, table | — | — |
tags | body | string[] | — | — |
target | body | object | null | — | — |
id | path | string (uuid) | • | The insight's uuid; slugs are not accepted here |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
kind | stringone of: trend, funnel, number, retention | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
grain | stringone of: day, week, month | — | — |
series | object[] | • | — |
target | object | null | — | — |
window | object | • | — |
display | stringone of: line, bar, bold_number, table | — | — |
formula | string | null | — | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
description | string | — | — |
GET/analytics/insights/:idOrSlug
Read one saved insight of the current product by its slug or its id. Returns the definition, not results.
MCP tool: analytics_insight_get
Parameters
| Name | In | Type | Required | Description |
|---|
idOrSlug | path | string | • | The insight's slug, or its uuid |
Response
Returns object.
| Field | Type | Always | Description |
|---|
id | string (uuid) | • | — |
kind | stringone of: trend, funnel, number, retention | • | — |
name | string | • | — |
slug | string | • | — |
tags | string[] | — | — |
grain | stringone of: day, week, month | — | — |
series | object[] | • | — |
target | object | null | — | — |
window | object | • | — |
display | stringone of: line, bar, bold_number, table | — | — |
formula | string | null | — | — |
created_at | string (date-time) | • | — |
created_by | string | null | • | — |
product_id | string (uuid) | • | — |
updated_at | string (date-time) | • | — |
description | string | — | — |
POST/analytics/insights/:idOrSlug/run
Run a saved insight of the current product and return its numbers: every series executed over the resolved window and aligned onto the same buckets, the formula evaluated bucket by bucket, a total per series, and whether the target was met. The window comes from the stored definition — relative windows and the current cycle are resolved at call time — and `from` and `to` override it for this call only, changing nothing stored. Use this rather than rebuilding the insight out of analytics_metric_query calls: the alignment and the formula are what make the numbers comparable.
MCP tool: analytics_insight_run
Parameters
| Name | In | Type | Required | Description |
|---|
from | body | string (date-time) | — | Inclusive window start; overrides the stored window |
to | body | string (date-time) | — | Inclusive window end; overrides the stored window |
idOrSlug | path | string | • | The insight's slug, or its uuid |
Response
Returns object.
| Field | Type | Always | Description |
|---|
extra | object | — | — |
total | object | • | — |
series | object | • | — |
window | object | • | — |
formula | object[] | null | • | — |
insight | object | null | • | — |
target_status | string | nullone of: met, missed | • | — |
POST/analytics/metrics/query
Compute declared metrics from the analytics semantic layer for the current product, bucketed by time and optionally grouped by one declared dimension. Deterministic: entity, metric and dimension names are resolved against the semantic catalog, never generated. Prefer this over analytics_query_run whenever the question is a metric over time — no LLM, no SQL generation. Where the catalog gives an entity a `propertiesColumn`, `group_by` and a filter dimension also accept `props.<key>` to read one raw event property; property values always compare as strings.
MCP tool: analytics_metric_query
Parameters
| Name | In | Type | Required | Description |
|---|
entity | body | string | • | Semantic view name from the catalog |
metrics | body | string[] | • | Declared metric names to compute |
grain | body | stringone of: day, week, month | • | Time bucket size |
from | body | string | • | Inclusive first day (UTC) |
to | body | string | • | Inclusive last day (UTC) |
group_by | body | string | — | One declared dimension, or `props.<key>`, to group by |
filters | body | object[] | — | Equality filters on declared dimensions, or on `props.<key>` event properties |
Response
Returns object.
| Field | Type | Always | Description |
|---|
meta | object | • | — |
series | object[] | • | — |
POST/analytics/persons/timeline
Return one resolved person's profile and their chronological activity across every identity-bearing semantic entity of the current product. Address the person either by person_id or by any single identifier (email, phone, users_id, anonymous_id), which is normalised exactly as the identity graph normalised it. Deterministic: no LLM, and only catalog-declared columns are returned. Prefer this over analytics_query_run whenever the question is about one specific person.
MCP tool: analytics_person_timeline
Parameters
| Name | In | Type | Required | Description |
|---|
person_id | body | string | — | Graph person id, when already known |
identifier | body | object | — | Any single identifier belonging to the person |
from | body | string | — | Inclusive first day (UTC); unbounded when omitted |
to | body | string | — | Inclusive last day (UTC); unbounded when omitted |
limit | body | integer | — | Maximum events to return, newest first |
Response
Returns object.
| Field | Type | Always | Description |
|---|
meta | object | • | — |
events | object[] | • | — |
person | object | • | — |
truncated | boolean | • | — |
POST/analytics/query
Answer a natural-language analytics question for the current product. Fallback surface: it routes the question to analytics_metric_query or analytics_funnel_run when it fits one of them and returns that tool's exact request and response in `structured`; it generates SQL only when neither fits. Call analytics_metric_query, analytics_funnel_run or analytics_person_timeline directly when you already know the shape of the question — those are deterministic and cheaper.
MCP tool: analytics_query_run
Parameters
| Name | In | Type | Required | Description |
|---|
q | body | string | • | Natural-language analytics question |
Response
Returns object.
| Field | Type | Always | Description |
|---|
sql | string | • | — |
rows | object[] | • | — |
answer | string | • | — |
truncated | boolean | • | — |
structured | object | — | — |
explanation | string | • | — |
POST/analytics/retention/run
Measure day-N retention over the analytics semantic layer for the current product: of the subjects whose FIRST matching cohort event falls in a bucket, how many produced a return event on day N (within `return_window_days` after it). The cohort key is `subject` — an event property (`props.<key>`, e.g. the customer product id) or `identity` for the entity's declared identity columns — and each subject is counted exactly once. Deterministic: entity and dimension names are resolved against the semantic catalog, never generated. A bucket whose day-N horizon has not elapsed yet is still returned, with `retained` and `rate` NULL rather than 0 — null means "not measurable yet", 0 means "measured, nobody came back", and a caller must not confuse them. `total` therefore covers the measurable buckets ONLY, so a half-elapsed cohort never drags the headline rate down; `meta.unmeasurable_buckets` says how many were left out.
MCP tool: analytics_retention_run
Parameters
| Name | In | Type | Required | Description |
|---|
entity | body | string | • | Semantic view name from the catalog |
subject | body | string | • | Cohort key: "identity" or `props.<key>` |
cohort | body | object | — | The starting event; empty filters mean any row of the entity |
return | body | object | — | The coming-back event; empty filters mean any row of the entity |
day | body | integer | • | N: a subject is retained if it has a return event at least N days after its cohort event |
return_window_days | body | integer | — | Length of the window that opens on day N; a return event must fall inside it |
from | body | string | • | Inclusive first day of the cohort range (UTC) |
to | body | string | • | Inclusive last day of the cohort range (UTC) |
grain | body | stringone of: day, week, month | • | Cohort bucket size, applied to each subject's FIRST cohort event |
Response
Returns object.
| Field | Type | Always | Description |
|---|
meta | object | • | — |
total | object | • | — |
buckets | object[] | • | — |
Was this page helpful?Thanks for your feedback!