Skip to Content
DocsAPIInsights

Insights

Run analytics queries programmatically against the same engine that powers dashboard charts, overview KPIs, and saved tiles. The Insights API is a server-side interface — it is not callable from browser clients.

Service: shared.insights.v1.InsightsService
Auth: Dual — private key (prv_…) via x-api-key or dashboard JWT via Authorization: Bearer. See Authentication.

Methods

Query

POST /shared.insights.v1.InsightsService/Query

Runs an analytics query and returns a typed result. The shape of the result depends on spec.insight_type (see Insight types).

Request — QueryRequest

FieldTypeRequiredDescription
specInsightQuerySpecYesThe query specification (insight type, events, breakdowns, filters).
time_rangeTimeRangeYesAbsolute start/end (from, to) as RFC 3339 timestamps. from must be before to.
granularityGranularityYesTime bucket size. See Granularities.

Response — QueryResponse

The response carries exactly one of the following fields, selected by spec.insight_type:

FieldTypePopulated when
trendsTrendsResultINSIGHT_TYPE_TRENDS
segmentationSegmentationResultINSIGHT_TYPE_SEGMENTATION
funnelFunnelResultINSIGHT_TYPE_FUNNEL
retentionRetentionResultINSIGHT_TYPE_RETENTION
user_flowUserFlowResultINSIGHT_TYPE_USER_FLOW

SegmentUsers

POST /shared.insights.v1.InsightsService/SegmentUsers

Returns a paginated list of distinct user IDs that match a set of event conditions within a time range. Useful for audience export or cross-referencing profiles.

FieldTypeDescription
time_rangeTimeRangeRequired.
eventsEventQuery[]Required, at least one.
filter_groupsFilterGroup[]Optional top-level filters.
filter_groups_operatorLogicalOperatorHow groups are combined (default AND).
page_sizeint320–1000.
page_tokenstringCursor from previous response.

Response: { distinct_ids: string[], next_page_token: string }.

GetFilterSchema

POST /shared.insights.v1.InsightsService/GetFilterSchema

Returns the set of known event kinds and property keys (auto, custom, profile) for the project. Use this to populate filter pickers. The response shape is common.v1.GetFilterSchemaResponse. Optionally scoped to a single event kind or filtered to specific PropertyValueType values.

GetPropertyValues

POST /shared.insights.v1.InsightsService/GetPropertyValues

Returns the distinct observed values for a specific property key. Useful for populating FILTER_OPERATOR_IN value lists.

FieldTypeRequiredDescription
property_keystringYesThe property to enumerate (e.g. $country, plan). Include the $ prefix for auto-properties.
sourcePropertySourceYesWhich namespace the key lives in: PROPERTY_SOURCE_AUTO, PROPERTY_SOURCE_CUSTOM, or PROPERTY_SOURCE_PROFILE.
event_kindstringNoRestrict observed values to a single event kind. Omit to scan across all events.

Response: { "values": string[] } — the distinct observed values.

{ "propertyKey": "$country", "source": "PROPERTY_SOURCE_AUTO" }

Insight types

InsightQuerySpec.insight_type selects the computation and the response field.

Enum valueDescription
INSIGHT_TYPE_TRENDSTime-series event counts or aggregations. One TrendSeries per (event, breakdown) combination.
INSIGHT_TYPE_SEGMENTATIONSingle scalar — total count or aggregation across the full time range, no time axis.
INSIGHT_TYPE_FUNNELMulti-step conversion funnel. Steps are the events array in order. Each series carries per-step counts; optionally includes per-step timing statistics when include_step_timing is true.
INSIGHT_TYPE_RETENTIONCohort retention matrix. events[0] is the starting event; events[1] (optional) is the return event. Returns cohorts bucketed by the query granularity.
INSIGHT_TYPE_USER_FLOWSankey / path graph showing transitions between events or property values. Requires a user_flow sub-spec; no events field.

Insight type constraints

  • INSIGHT_TYPE_FUNNEL — requires at least one event; supports breakdowns (max 5); supports conversion_window (whole seconds, min 1 s); supports include_step_timing.
  • INSIGHT_TYPE_RETENTION — requires at least one event; accepts at most 2 (events[0] = start, events[1] = return).
  • INSIGHT_TYPE_SEGMENTATION — does not support breakdowns.
  • INSIGHT_TYPE_USER_FLOW — requires a user_flow sub-spec; events must be empty; breakdowns are not supported.
  • INSIGHT_TYPE_TRENDS / INSIGHT_TYPE_SEGMENTATION — support numeric aggregations (AGGREGATION_TYPE_SUM, AVG, MIN, MAX); these are not valid for funnel or retention.

Granularities

QueryRequest.granularity controls the time-bucket width and imposes a maximum query range.

Enum valueBucket widthMaximum time range
GRANULARITY_MINUTE1 minute6 hours
GRANULARITY_HOUR1 hour14 days
GRANULARITY_DAY1 day365 days
GRANULARITY_WEEK1 week~4 years (1461 days)
GRANULARITY_MONTH1 month~10 years (3652 days)

InsightQuerySpec fields

FieldTypeDescription
insight_typeInsightTypeRequired. Selects the computation and response shape.
eventsEventQuery[]Event series (for trends, segmentation, funnel, retention). Each entry selects one event kind with optional filters and an aggregation type.
breakdownsBreakdown[]Group results by up to 5 properties ({ property: string }). Not supported for segmentation or user flow.
breakdown_limitint32Cap on number of breakdown values returned (0–100). Requires at least one breakdown.
filter_groupsFilterGroup[]Top-level property filters. Multiple groups are combined by filter_groups_operator.
filter_groups_operatorLogicalOperatorHow filter groups are combined. Defaults to LOGICAL_OPERATOR_AND.
conversion_windowDurationFunnel only. Maximum time from step 1 to last step per user. Whole seconds, min 1 s. Absent = no constraint.
include_step_timingboolFunnel only. When true, each non-entry step includes StepTiming (avg, median, p95, 8-bucket histogram).
sessionSessionQueryTrends/segmentation only. Query session-level metrics instead of events. events must be empty when set.
user_flowUserFlowQueryUser-flow only. Configures the Sankey graph (node kind, max hops, max nodes, max links).

EventQuery

FieldTypeDescription
eventEventFilterEvent kind + optional per-event property filters.
aggregationAggregationTypeDefaults to AGGREGATION_TYPE_TOTAL.
aggregation_propertystringRequired for SUM, AVG, MIN, MAX. Property name to aggregate (e.g. revenue).

Aggregation types

Enum valueDescription
AGGREGATION_TYPE_TOTALTotal event occurrences.
AGGREGATION_TYPE_UNIQUE_USERSCount of distinct users.
AGGREGATION_TYPE_PER_USER_AVGAverage events per user.
AGGREGATION_TYPE_SUMSum of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_AVGMean of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_MINMinimum of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_MAXMaximum of a numeric property. Requires aggregation_property.

Filter model

Filters are expressed as FilterGroup objects inside spec.filter_groups. Each group contains one or more PropertyFilter entries combined by the group’s own operator. Groups are then combined by spec.filter_groups_operator.

FilterGroup

{ "filters": [ { "property": "plan", "operator": "FILTER_OPERATOR_EQUALS", "value": "pro" }, { "property": "$country", "operator": "FILTER_OPERATOR_IN", "values": ["US", "CA"] } ], "operator": "LOGICAL_OPERATOR_AND" }

Filter operators (FilterOperator)

Enum valueValue fields usedDescription
FILTER_OPERATOR_EQUALSvalueExact match.
FILTER_OPERATOR_NOT_EQUALSvalueExcludes exact match.
FILTER_OPERATOR_CONTAINSvalueSubstring match.
FILTER_OPERATOR_NOT_CONTAINSvalueExcludes substring match.
FILTER_OPERATOR_IS_SETProperty exists.
FILTER_OPERATOR_IS_NOT_SETProperty is absent.
FILTER_OPERATOR_LTEvalue (numeric)Less than or equal.
FILTER_OPERATOR_GTEvalue (numeric)Greater than or equal.
FILTER_OPERATOR_LTvalue (numeric)Strictly less than.
FILTER_OPERATOR_GTvalue (numeric)Strictly greater than.
FILTER_OPERATOR_INvaluesMatch any of a list.
FILTER_OPERATOR_NOT_INvaluesExclude all of a list.
FILTER_OPERATOR_BETWEENvalues[0], values[1] (numeric, ordered)Inclusive range.
FILTER_OPERATOR_NOT_BETWEENvalues[0], values[1] (numeric, ordered)Outside range.

Logical operators (LogicalOperator)

Enum valueDescription
LOGICAL_OPERATOR_ANDAll conditions must match (default).
LOGICAL_OPERATOR_ORAt least one condition must match.

Property names follow the pattern ^\\$?[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*$. Auto-properties use their flat $ key (e.g. $country, $browser); a dotted name addresses a nested key inside a custom property’s JSON (e.g. metadata.tier). For filterable auto-properties see Auto-properties.

Session metrics

When spec.session is set, the query measures session-level data instead of individual events. spec.events must be empty.

Enum valueDescriptionRestrictions
SESSION_METRIC_SESSIONSCount of distinct sessions started in the window.Trends or segmentation.
SESSION_METRIC_AVG_DURATIONAverage session duration in seconds (last event − first event).Trends or segmentation.
SESSION_METRIC_BOUNCE_RATEPercentage of sessions with exactly one event (after optional scope filter).Trends or segmentation.
SESSION_METRIC_ENTRYCount sessions by their first matching event’s breakdown value (entry page).Trends + exactly one breakdown.
SESSION_METRIC_EXITCount sessions by their last matching event’s breakdown value (exit page).Trends + exactly one breakdown.

SessionQuery.scope (optional EventFilter) restricts which events participate in the metric. An empty scope considers all events in the session.

A daily time series of unique users who fired page_view, broken down by $country, over the last 30 days.

POST /shared.insights.v1.InsightsService/Query Content-Type: application/json Connect-Protocol-Version: 1 x-api-key: prv_…
{ "spec": { "insight_type": "INSIGHT_TYPE_TRENDS", "events": [ { "event": { "kind": "page_view" }, "aggregation": "AGGREGATION_TYPE_UNIQUE_USERS" } ], "breakdowns": [ { "property": "$country" } ], "breakdown_limit": 10 }, "time_range": { "from": "2026-05-06T00:00:00Z", "to": "2026-06-05T00:00:00Z" }, "granularity": "GRANULARITY_DAY" }

Response sketch:

{ "trends": { "series": [ { "event_kind": "page_view", "breakdown": { "$country": "US" }, "points": [ { "time": "2026-05-06T00:00:00Z", "value": 412 }, { "time": "2026-05-07T00:00:00Z", "value": 389 } ] }, { "event_kind": "page_view", "breakdown": { "$country": "GB" }, "points": [ { "time": "2026-05-06T00:00:00Z", "value": 104 }, { "time": "2026-05-07T00:00:00Z", "value": 97 } ] } ] } }

Each series entry corresponds to one (event_kind, breakdown) pair. points are in ascending time order with one entry per granularity bucket.

Worked example: FUNNEL query

POST /shared.insights.v1.InsightsService/Query Content-Type: application/json Connect-Protocol-Version: 1 x-api-key: prv_…
{ "spec": { "insight_type": "INSIGHT_TYPE_FUNNEL", "events": [ { "event": { "kind": "signup_started" } }, { "event": { "kind": "signup_completed" } }, { "event": { "kind": "purchase" } } ], "conversion_window": "604800s" }, "time_range": { "from": "2026-05-01T00:00:00Z", "to": "2026-06-01T00:00:00Z" }, "granularity": "GRANULARITY_DAY" }

Response sketch:

{ "funnel": { "series": [ { "breakdown": {}, "steps": [ { "event_kind": "signup_started", "total": 1000 }, { "event_kind": "signup_completed", "total": 650 }, { "event_kind": "purchase", "total": 120 } ] } ] } }

With include_step_timing: true, each non-entry step gains a timing object:

{ "event_kind": "signup_completed", "total": 650, "timing": { "avg": "180s", "median": "95s", "p95": "1200s", "distribution": [ { "label": "0-30s", "upper_bound": "30s", "count": 78 }, { "label": "30s-2m", "upper_bound": "120s", "count": 210 } ] } }

The distribution array above is truncated for brevity — it always contains exactly 8 buckets in the canonical order, and the 8 boundaries are fixed (a full response returns all 8).

Performance notes

Insights queries run against ClickHouse. Query time scales with:

  • Time range × granularity — wider ranges at fine granularities scan more partitions.
  • Breakdown cardinality — avoid very high-cardinality breakdowns (e.g. user ID). Use breakdown_limit to cap result size.
  • Funnel step count — funnel supports at most 20 steps.
Last updated on