Skip to content

Insights API

Run trends, funnel, retention, segmentation and user-flow queries programmatically with a private key.

Updated View as Markdown

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

Field Type Required Description
spec InsightQuerySpec Yes The query specification (insight type, events, breakdowns, filters).
time_range TimeRange Yes Absolute start/end (from, to) as RFC 3339 timestamps. from must be before to.
granularity Granularity Yes Time bucket size. See Granularities.

Response — QueryResponse

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

Field Type Populated when
trends TrendsResult INSIGHT_TYPE_TRENDS
segmentation SegmentationResult INSIGHT_TYPE_SEGMENTATION
funnel FunnelResult INSIGHT_TYPE_FUNNEL
retention RetentionResult INSIGHT_TYPE_RETENTION
user_flow UserFlowResult INSIGHT_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.

Field Type Description
time_range TimeRange Required.
events EventQuery[] Required, at least one.
filter_groups FilterGroup[] Optional top-level filters.
filter_groups_operator LogicalOperator How groups are combined (default AND).
page_size int32 0–1000.
page_token string Cursor 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.

Field Type Required Description
property_key string Yes The property to enumerate (e.g. $country, plan). Include the $ prefix for auto-properties.
source PropertySource Yes Which namespace the key lives in: PROPERTY_SOURCE_AUTO, PROPERTY_SOURCE_CUSTOM, or PROPERTY_SOURCE_PROFILE.
event_kind string No Restrict 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 value Description
INSIGHT_TYPE_TRENDS Time-series event counts or aggregations. One TrendSeries per (event, breakdown) combination.
INSIGHT_TYPE_SEGMENTATION Single scalar — total count or aggregation across the full time range, no time axis.
INSIGHT_TYPE_FUNNEL Multi-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_RETENTION Cohort 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_FLOW Sankey / 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 value Bucket width Maximum time range
GRANULARITY_MINUTE 1 minute 6 hours
GRANULARITY_HOUR 1 hour 14 days
GRANULARITY_DAY 1 day 365 days
GRANULARITY_WEEK 1 week ~4 years (1461 days)
GRANULARITY_MONTH 1 month ~10 years (3652 days)

InsightQuerySpec fields

Field Type Description
insight_type InsightType Required. Selects the computation and response shape.
events EventQuery[] Event series (for trends, segmentation, funnel, retention). Each entry selects one event kind with optional filters and an aggregation type.
breakdowns Breakdown[] Group results by up to 5 properties ({ property: string }). Not supported for segmentation or user flow.
breakdown_limit int32 Cap on number of breakdown values returned (0–100). Requires at least one breakdown.
filter_groups FilterGroup[] Top-level property filters. Multiple groups are combined by filter_groups_operator.
filter_groups_operator LogicalOperator How filter groups are combined. Defaults to LOGICAL_OPERATOR_AND.
conversion_window Duration Funnel only. Maximum time from step 1 to last step per user. Whole seconds, min 1 s. Absent = no constraint.
include_step_timing bool Funnel only. When true, each non-entry step includes StepTiming (avg, median, p95, 8-bucket histogram).
session SessionQuery Trends/segmentation only. Query session-level metrics instead of events. events must be empty when set.
user_flow UserFlowQuery User-flow only. Configures the Sankey graph (node kind, max hops, max nodes, max links).

EventQuery

Field Type Description
event EventFilter Event kind + optional per-event property filters.
aggregation AggregationType Defaults to AGGREGATION_TYPE_TOTAL.
aggregation_property string Required for SUM, AVG, MIN, MAX. Property name to aggregate (e.g. revenue).

Aggregation types

Enum value Description
AGGREGATION_TYPE_TOTAL Total event occurrences.
AGGREGATION_TYPE_UNIQUE_USERS Count of distinct users.
AGGREGATION_TYPE_PER_USER_AVG Average events per user.
AGGREGATION_TYPE_SUM Sum of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_AVG Mean of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_MIN Minimum of a numeric property. Requires aggregation_property.
AGGREGATION_TYPE_MAX Maximum 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 value Value fields used Description
FILTER_OPERATOR_EQUALS value Exact match.
FILTER_OPERATOR_NOT_EQUALS value Excludes exact match.
FILTER_OPERATOR_CONTAINS value Substring match.
FILTER_OPERATOR_NOT_CONTAINS value Excludes substring match.
FILTER_OPERATOR_IS_SET Property exists.
FILTER_OPERATOR_IS_NOT_SET Property is absent.
FILTER_OPERATOR_LTE value (numeric) Less than or equal.
FILTER_OPERATOR_GTE value (numeric) Greater than or equal.
FILTER_OPERATOR_LT value (numeric) Strictly less than.
FILTER_OPERATOR_GT value (numeric) Strictly greater than.
FILTER_OPERATOR_IN values Match any of a list.
FILTER_OPERATOR_NOT_IN values Exclude all of a list.
FILTER_OPERATOR_BETWEEN values[0], values[1] (numeric, ordered) Inclusive range.
FILTER_OPERATOR_NOT_BETWEEN values[0], values[1] (numeric, ordered) Outside range.

Logical operators (LogicalOperator)

Enum value Description
LOGICAL_OPERATOR_AND All conditions must match (default).
LOGICAL_OPERATOR_OR At 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 value Description Restrictions
SESSION_METRIC_SESSIONS Count of distinct sessions started in the window. Trends or segmentation.
SESSION_METRIC_AVG_DURATION Average session duration in seconds (last event − first event). Trends or segmentation.
SESSION_METRIC_BOUNCE_RATE Percentage of sessions with exactly one event (after optional scope filter). Trends or segmentation.
SESSION_METRIC_ENTRY Count sessions by their first matching event’s breakdown value (entry page). Trends + exactly one breakdown.
SESSION_METRIC_EXIT Count 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.
Navigation

Type to search…

↑↓ navigate↵ selectEsc close