
Product analytics and experimentation platform - track events, analyze user funnels, run A/B tests, manage feature flags, and query session recordings.
Docs Search
Use this tool to search the PostHog documentation for information that can help the user with their request. Use it as a fallback when you cannot answer the user's request using other tools in this MCP. Only use this tool for PostHog related questions.
Experiment Get All
Get all experiments in the project.
Experiment Create
Create a comprehensive A/B test experiment. PROCESS: 1) Understand experiment goal and hypothesis 2) Search existing feature flags with 'feature-flags-get-all' tool first and suggest reuse or new key 3) Help user define success metrics by asking what they want to optimize 4) MOST IMPORTANT: Use 'event-definitions-list' tool to find available events in their project 5) For funnel metrics, ask for specific event sequence (e.g., ['product_view', 'add_to_cart', 'purchase']) and use funnel_steps parameter 6) Configure variants (default 50/50 control/test unless they specify otherwise) 7) Set targeting criteria if needed.
Experiment Delete
Delete an experiment by ID.
Experiment Update
Update an existing experiment by ID. Can update name, description, lifecycle state, variants, metrics, and other properties. RESTART WORKFLOW: To restart a concluded experiment, set end_date=null, conclusion=null, conclusion_comment=null, and optionally set a new start_date. To make it draft again, also set start_date=null. COMMON PATTERNS: Launch draft (set start_date), stop running (set end_date + conclusion), archive (set archived=true), modify variants (update parameters.feature_flag_variants). NOTE: feature_flag_key cannot be changed after creation.
Experiment Get
Get details of a specific experiment by ID.
Experiment Results Get
Get comprehensive experiment results including all metrics data (primary and secondary) and exposure data. This tool fetches the experiment details and executes the necessary queries to get complete experiment results. Only works with new experiments (not legacy experiments).
Insight Create From Query
Create an insight from a query that you have previously tested with 'query-run'. You should check the query runs, before creating an insight. Do not create an insight before running the query, unless you know already that it is correct (e.g. you are making a minor modification to an existing query you have seen).
Insight Delete
Delete an insight by ID (soft delete - marks as deleted).
Insight Get
Get a specific insight by ID.
Insight Query
Execute a query on an existing insight to get its results/data. Provide the insight ID to retrieve the current query results.
Insights Get All
Get all insights in the project with optional filtering. Can filter by saved status, favorited status, or search term.
Insight Update
Update an existing insight by ID. Can update name, description, filters, and other properties. You should get the insight before update it to see it's current query structure, and only modify the parts needed to answer the user's request.
Query Run
You should use this to answer questions that a user has about their data and for when you want to create a new insight. You can use 'event-definitions-list' to get events to use in the query, and 'event-properties-list' to get properties for those events. It can run a trend, funnel, paths or HogQL query. Where possible, use a trend, funnel or paths query rather than a HogQL query, unless you know the HogQL is correct (e.g. it came from a previous insight.). Use PathsQuery to visualize user flows and navigation patterns — set includeEventTypes to ['hogql'] with a pathsHogQLExpression for custom path steps.
Query Generate Hogql From Question
This is a slow tool, and you should only use it once you have tried to create a query using the 'query-run' tool, or the query is too complicated to create a trend / funnel. Queries project's PostHog data based on a provided natural language question - don't provide SQL query as input but describe the output you want. When giving the results back to the user, first show the SQL query that was used, then provide results in easily readable format. You should also offer to save the query as an insight if the user wants to.
Evaluations Get
List LLM analytics evaluations for the project. Evaluations automatically score AI generations for quality, relevance, safety, and other criteria. Supports optional search by name/description and filtering by enabled status. Evaluation results are stored as '$ai_evaluation' events — to query results, use the execute-sql or query-run tool with a HogQL query filtering on event = '$ai_evaluation'. Key properties: $ai_evaluation_id (evaluation UUID), $ai_evaluation_name, $ai_target_event_id (generation event UUID), $ai_trace_id, $ai_evaluation_result (boolean pass/fail), $ai_evaluation_reasoning (text), $ai_evaluation_applicable (boolean, false = N/A).
Evaluation Get
Get a specific LLM analytics evaluation by its UUID. Returns full details including name, type (llm_judge or hog), configuration, conditions, and enabled status.
Evaluation Create
Create a new LLM analytics evaluation. Two types are supported: 'llm_judge' uses an LLM to score generations against a prompt you define (for subjective checks like tone, helpfulness, hallucination detection), and 'hog' runs deterministic code against each generation (for rule-based checks like format validation, keyword detection, length limits). For llm_judge evaluations, provide a prompt in evaluation_config and a model_configuration. For hog evaluations, provide source code in evaluation_config.
Evaluation Update
Update an existing LLM analytics evaluation. You can change the name, description, enabled status, evaluation config (prompt or source code), and output config. Use this to enable/disable evaluations or modify their scoring logic.
Evaluation Delete
Delete an LLM analytics evaluation (soft delete). The evaluation will be marked as deleted and will no longer run.
Evaluation Run
Trigger an evaluation run on a specific $ai_generation event. This executes the evaluation (either LLM judge or Hog code) against the target event asynchronously via a background workflow. The run is async — it returns a workflow_id and status 'started'. Results are written as '$ai_evaluation' events once complete. To check results after triggering a run, query events with: SELECT properties.$ai_evaluation_result as result, properties.$ai_evaluation_reasoning as reasoning FROM events WHERE event = '$ai_evaluation' AND properties.$ai_evaluation_id = '<evaluation_uuid>' AND properties.$ai_target_event_id = '<generation_event_uuid>' ORDER BY timestamp DESC LIMIT 1.
Evaluation Test Hog
Test Hog evaluation code against recent $ai_generation events without persisting results. Compiles the provided Hog source code and runs it against a sample of recent events (up to 10 from the last 7 days). Returns per-event results with input/output previews, pass/fail verdicts, and any errors. Use this to validate Hog evaluation logic before enabling it.
Get Llm Total Costs For Project
Fetches the total LLM daily costs for each model for a project over a given number of days. If no number of days is provided, it defaults to 7. The results are sorted by model name. The total cost is rounded to 4 decimal places. The query is executed against the project's data warehouse. Show the results as a Markdown formatted table with the following information for each model: Model name, Total cost in USD, Each day's date, Each day's cost in USD. Write in bold the model name with the highest total cost. Properly render the markdown table in the response.
Organization Details Get
Get the details of the active organization.
Organizations Get
Get the organizations the user has access to.
Switch Organization
Change the active organization from the default organization. You should only use this tool if the user asks you to change the organization - otherwise, the default organization will be used.
Projects Get
Fetches projects that the user has access to in the current organization.
Event Definitions List
List all event definitions in the project with optional filtering. Can filter by search term.
Event Definition Update
Update event definition metadata. Can update description, tags, mark status as verified or hidden. Use exact event name like '$pageview' or 'user_signed_up'.
Properties List
List properties for events or persons. If fetching event properties, you must provide an event name.
Switch Project
Change the active project from the default project. You should only use this tool if the user asks you to change the project - otherwise, the default project will be used.
Survey Create
Creates a new survey in the project. Surveys can be popover or API-based and support various question types including open-ended, multiple choice, rating, and link questions. Once created, you should ask the user if they want to add the survey to their application code.
Survey Get
Get a specific survey by ID. Returns the survey configuration including questions, targeting, and scheduling details.
Surveys Get All
Get all surveys in the project with optional filtering. Can filter by search term or use pagination.
Survey Update
Update an existing survey by ID. Can update name, description, questions, scheduling, and other survey properties.
Survey Delete
Delete a survey by ID (soft delete - marks as archived).
Surveys Global Stats
Get aggregated response statistics across all surveys in the project. Includes event counts (shown, dismissed, sent), unique respondents, conversion rates, and timing data. Supports optional date filtering.
Survey Stats
Get response statistics for a specific survey. Includes detailed event counts (shown, dismissed, sent), unique respondents, conversion rates, and timing data. Supports optional date filtering.
Logs Query
Search and query logs in the project. Supports filtering by severity levels (trace, debug, info, warn, error, fatal), service names, date range, and free text search. Returns log entries with their attributes, timestamps, and trace information. Supports pagination via cursor.
Logs List Attributes
List available log attributes in the project. Use this to discover what attributes you can filter on when querying logs. Supports filtering by attribute type (log or resource) and searching by attribute name.
Logs List Attribute Values
Get possible values for a specific log attribute. Use this to discover what values exist for a given attribute key, which helps when building log queries with filters.
Entity Search
Search for PostHog entities by name or description. Can search across multiple entity types including insights, dashboards, experiments, feature flags, notebooks, actions, cohorts, event definitions, and surveys. Use this to find entities when you know part of their name. Returns matching entities with their IDs and URLs.
Debug Mcp Ui Apps
Debug tool for testing MCP Apps SDK integration. Returns sample data displayed in an interactive UI app with component showcase. Use this to verify that MCP Apps are working correctly.
Actions Get All
Get all actions in the project. Actions are reusable event definitions that can combine multiple trigger conditions (page views, clicks, form submissions) into a single trackable event for use in insights and funnels. Supports pagination with limit and offset parameters. Note: Search/filtering by name is not supported on this endpoint.
Action Create
Create a new action in the project. Actions define reusable event triggers based on page views, clicks, form submissions, or custom events. Each action can have multiple steps (OR conditions). Use actions to create composite events for insights and funnels. Example: Create a 'Sign Up Click' action with steps matching button clicks on the signup page.
Action Get
Get a specific action by ID. Returns the action configuration including all steps and their trigger conditions.
Action Update
Update an existing action by ID. Can update name, description, steps, tags, and Slack notification settings.
Action Delete
Delete an action by ID (soft delete - marks as deleted). The action will no longer appear in lists but historical data is preserved.
Cohorts List
List all cohorts in the project. Returns a summary of each cohort including id, name, description, count (person count), is_static (cohort type), and created_at timestamp. Use 'cohorts-retrieve' with the cohort ID to get full details including filters, calculation status, and query definition.
Cohorts Create
Create a new cohort. For dynamic cohorts, provide 'filters' with AND/OR groups of property conditions (person properties, behavioral filters, or cohort references). For static cohorts, set 'is_static: true' then use the 'cohorts-add-persons-to-static-cohort-partial-update' tool to add person UUIDs.
Cohorts Retrieve
Get a specific cohort by ID. Returns the cohort name, description, filters (for dynamic cohorts), count of matching users, and calculation status.
Cohorts Partial Update
Update an existing cohort's name, description, or filters. Changing filters on a dynamic cohort triggers recalculation. To soft-delete a cohort, set 'deleted: true'.
Cohorts Add Persons To Static Cohort Partial Update
Add persons to a static cohort by their UUIDs. Only works for static cohorts (is_static: true).
Cohorts Rm Person From Static Cohort Partial Update
Remove a person from a static cohort by their UUID. Only works for static cohorts (is_static: true). The person must exist in the project. Idempotent: removing a person who exists but is not a member of the cohort succeeds silently.
Dashboards Get All
Get all dashboards in the project with optional filtering by pinned status or search term. Returns name, description, pinned status, tags, and creation metadata.
Dashboard Create
Create a new dashboard. Provide a name and optional description, tags, and pinned status. Can also create from a template or duplicate an existing dashboard.
Dashboard Get
Get a specific dashboard by ID. Returns the full dashboard including all tiles with their insights and layout information.
Dashboard Update
Update an existing dashboard by ID. Can update name, description, pinned status, tags, filters, and restriction level.
Dashboard Delete
Delete a dashboard by ID. The dashboard will be soft-deleted and no longer appear in lists.
Dashboard Reorder Tiles
Reorder tiles on a dashboard by providing an array of tile IDs in the desired display order. Computes a 2-column grid layout (6 columns wide, 5 rows tall per tile). First, use dashboard-get to see current tile IDs.
View List
List all data warehouse saved queries (views) in the project. Returns each view's name, materialization status, sync frequency, column schema, latest error, and last run timestamp. Use this to discover available views before querying them in HogQL.
View Get
Get a specific data warehouse saved query (view) by ID. Returns the full view definition including the HogQL query, column schema, materialization status, sync frequency, and run history metadata.
View Run History
Get the 5 most recent materialization run statuses for a saved query. Each entry includes the run status and timestamp. Use this to monitor whether materialization is running successfully.
Error Tracking Issues List
List all error tracking issues in the project. Returns issues with status, volume, first/last seen timestamps, and assignee info.
Error Tracking Issues Retrieve
Get a specific error tracking issue by ID. Returns full issue details including status, description, volume, and metadata.
Error Tracking Issues Partial Update
Update an error tracking issue. Can change status (active, resolved, suppressed), assign to a user, or update description.
Query Error Tracking Issues
Query error tracking issues to find, filter, and inspect errors in the project. Returns aggregated metrics per issue including occurrence count, affected users, sessions, and volume data. Use 'read-data-schema' to discover available events, actions, and properties for filters. This is a unified query tool — use it both to list issues and to get details on a specific issue: - **List issues**: omit `issueId` to get a filtered, sorted list of error tracking issues. - **Get issue details**: provide `issueId` to get aggregated metrics for a single issue. Use `error-tracking-issues-retrieve` to get the full issue model (description, assignee, external references) and `error-tracking-issues-partial-update` to change status or assignee. CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters via the `filterGroup` field to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional filtering and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `$browser`, `$os`, or `$geoip_country_code`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, the default is the last 7 days. # Parameters ## issueId (optional) When provided, returns aggregated metrics for a single error tracking issue. When omitted, returns a paginated list of issues matching the filters. ## status Filter by issue status. Available values: `active`, `resolved`, `suppressed`, `pending_release`, `archived`, `all`. Defaults to `active`. ## orderBy Field to sort results by: `occurrences`, `last_seen`, `first_seen`, `users`, `sessions`. Defaults to `occurrences`. ## searchQuery Free-text search across exception type, message, and stack frames. Use this when the user is looking for a specific error by name or message content. ## assignee Filter issues by assignee. The value is a user ID. Use this when the user asks to see errors assigned to a specific person. ## filterGroup A flat list of property filters to narrow results. Each filter specifies a property key, operator, type (event/person/session/group), and value. See the "Property filters" section above for usage guidelines and supported operators. ## volumeResolution Controls the granularity of the volume chart data returned with each issue. Use `1` (default) for list views where you want a volume sparkline. Use `0` when you only need aggregate counts without volume data. ## dateRange Date range to filter results. Defaults to the last 7 days (`-7d`). - `date_from`: Start of the range. Accepts ISO 8601 timestamps (e.g., `2024-01-15T00:00:00Z`) or relative formats: `-7d`, `-2w`, `-1m`, `-1h`, `-1mStart`, `-1yStart`. - `date_to`: End of the range. Same format. Omit or null for "now". ## limit / offset Pagination controls. `limit` defaults to 50. # Examples ## List all active errors sorted by occurrence count ```json {} ``` All defaults apply: `status: "active"`, `orderBy: "occurrences"`, `dateRange: { "date_from": "-7d" }`. ## Search for a specific error ```json { "searchQuery": "TypeError: Cannot read property", "limit": 10 } ``` ## Get details for a specific issue ```json { "issueId": "01234567-89ab-cdef-0123-456789abcdef", "volumeResolution": 0 } ``` ## List resolved errors from the last 30 days ```json { "status": "resolved", "dateRange": { "date_from": "-30d" }, "orderBy": "last_seen" } ``` ## Find most recent errors ```json { "orderBy": "first_seen", "orderDirection": "DESC", "dateRange": { "date_from": "-24h" } } ``` ## Errors from Chrome users only ```json { "filterGroup": [{ "key": "$browser", "operator": "exact", "type": "event", "value": ["Chrome"] }] } ``` ## Errors from US users in the last 30 days ```json { "filterGroup": [{ "key": "$geoip_country_code", "operator": "exact", "type": "event", "value": ["US"] }], "dateRange": { "date_from": "-30d" } } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution.
Feature Flag Get All
Get feature flags in the current project. Supports list filters including search by feature flag key or name (case-insensitive), then use the returned ID for get/update/delete tools.
Feature Flag Get Definition
Get a feature flag by ID.
Create Feature Flag
Create a feature flag in the current project.
Update Feature Flag
Update a feature flag by ID in the current project.
Delete Feature Flag
Soft-delete a feature flag by ID in the current project.
Feature Flags Dependent Flags Retrieve
Get other active feature flags that depend on this flag. Use this to understand flag dependency chains before making changes to a flag's rollout conditions or disabling it.
Feature Flags Status Retrieve
Check the health and evaluation status of a feature flag by ID. Returns a status (active, stale, deleted, or unknown) and a human-readable reason explaining the status.
Feature Flags Evaluation Reasons Retrieve
Debug why feature flags evaluate a certain way for a given user. Provide a distinct_id and optionally groups to see each flag's evaluated value and the reason for that evaluation (e.g. condition_match, no_condition_match, disabled).
Feature Flags User Blast Radius Create
Assess the impact of a feature flag release condition before applying it. Provide a condition object and optionally a group_type_index to see how many users would be affected relative to the total user count.
Feature Flags Copy Flags Create
Copy a feature flag from one project to other projects within the same organization. Provide the flag key, source project ID, and a list of target project IDs. Optionally copy scheduled changes with copy_schedule. Returns lists of successful and failed copies.
Scheduled Changes List
List scheduled changes in the current project. Filter by model_name=FeatureFlag and record_id to see schedules for a specific flag. Returns pending, executed, and failed schedules with their payloads and timing. Use this to check what changes are queued for a feature flag before modifying it.
Scheduled Changes Get
Get a single scheduled change by ID. Returns the full details including the payload, schedule timing, execution status, and any failure reason.
Scheduled Changes Create
Schedule a future change to a feature flag. Supported operations: 'update_status' (enable/disable), 'add_release_condition', and 'update_variants'. Provide the flag ID as record_id, model_name as "FeatureFlag", a payload with the operation and value, and a scheduled_at datetime.
Scheduled Changes Update
Update a pending scheduled change by ID. You can modify the payload, scheduled_at time, or recurrence settings. Cannot change the target record (record_id) or model type (model_name).
Scheduled Changes Delete
Delete a scheduled change by ID. This permanently removes the scheduled change and it will not be executed.
Prompt List
List all LLM prompts stored for the current team. Optionally filter by name. Returns paginated prompt summaries. By default, only prompt metadata is returned, not full prompt content.
Prompt Get
Get a specific LLM prompt by name, including its full content. Uses the cached endpoint for fast retrieval.
Prompt Create
Create a new LLM prompt for the current team. Requires a unique name and prompt content (string or JSON object).
Prompt Update
Publish a new version of an existing LLM prompt by name. Name is immutable after creation. You can either provide the full prompt content via 'prompt', or use 'edits' for incremental find/replace updates. Each edit must have 'old' (text to find, must match exactly once) and 'new' (replacement text). Edits are applied sequentially. Only one of 'prompt' or 'edits' may be provided.
Prompt Duplicate
Duplicate an existing LLM prompt under a new name. Copies the latest version's content to create a new prompt at version 1. Useful for forking a prompt or as a way to rename since names are immutable after creation.
Proxy List
List all managed reverse proxies configured for the current organization. Returns each proxy's domain, CNAME target, provisioning status, and the maximum number of proxies allowed by the current plan. Use this to check whether a reverse proxy is set up before recommending one.
Proxy Get
Get full details of a specific reverse proxy by ID. Returns the domain, CNAME target (the DNS record value the user needs to configure), current provisioning status, and any error or warning messages. Use this to debug why a proxy isn't working or to check DNS verification status.
Workflows List
List all workflows in the project. Returns workflows with their name, description, status (draft/active/archived), version, trigger configuration, and timestamps.
Workflows Get
Get a specific workflow by ID. Returns the full workflow definition including trigger, edges, actions, exit condition, and variables.
Query Trends
Run a trends query to analyze metrics over time. Trends insights visualize events over time using time series. They're useful for finding patterns in historical data. Use 'read-data-schema' to discover available events, actions, and properties for filters and breakdowns. The trends insights have the following features: - The insight can show multiple trends in one request. - Custom formulas can calculate derived metrics, like `A/B*100` to calculate a ratio. - Filter and break down data using multiple properties. - Compare with the previous period and sample data. - Apply various aggregation types, like sum, average, etc., and chart types. Examples of use cases include: - How the product's most important metrics change over time. - Long-term patterns, or cycles in product's usage. - The usage of different features side-by-side. - How the properties of events vary using aggregation (sum, average, etc). - Users can also visualize the same data points in a variety of ways. CRITICAL: Be minimalist. Only include filters, breakdowns, and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Trends guidelines Trends insights enable users to plot data from people, events, and properties however they want. They're useful for finding patterns in data, as well as monitoring product usage. Users can use multiple independent series in a single query to see trends. They can also use a formula to calculate a metric. Each series has its own set of property filters. Trends insights do not require breakdowns or filters by default. ## Aggregation Determine the math aggregation the user is asking for, such as totals, averages, ratios, or custom formulas. If not specified, choose a reasonable default based on the event type (e.g., total count). By default, the total count should be used. You can aggregate data by events, event's property values, groups, or users. If you're aggregating by users or groups, there's no need to check for their existence. Available math aggregation types for the event count are: - total count - average - minimum - maximum - median - 90th percentile - 95th percentile - 99th percentile - unique users - unique sessions - weekly active users - daily active users - first time for a user - unique groups (requires `math_group_type_index` to be set to the group type index from the group mapping) Available math aggregation types for event's property values are: - average - sum - minimum - maximum - median - 90th percentile - 95th percentile - 99th percentile Available math aggregation types counting number of events completed per user (intensity of usage) are: - average - minimum - maximum - median - 90th percentile - 95th percentile - 99th percentile Examples of using aggregation types: - `unique users` to find how many distinct users have logged the event per a day. - `average` by the `$session_duration` property to find out what was the average session duration of an event. - `99th percentile by users` to find out what was the 99th percentile of the event count by users. ## Math formulas If the math aggregation is more complex or not listed above, use custom formulas to perform mathematical operations like calculating percentages or metrics. If you use a formula, you should use the following syntax: `A/B`, where `A` and `B` are the names of the series. You can combine math aggregations and formulas. When using a formula, you should: - Identify and specify **all** events and actions needed to solve the formula. - Carefully review the list of available events and actions to find appropriate entities for each part of the formula. - Ensure that you find events and actions corresponding to both the numerator and denominator in ratio calculations. Examples of using math formulas: - If you want to calculate the percentage of users who have completed onboarding, you need to find and use events or actions similar to `$identify` and `onboarding complete`, so the formula will be `A / B * 100`, where `A` is `onboarding complete` (unique users) and `B` is `$identify` (unique users). - To calculate conversion rate: `A / B * 100` where A is conversions and B is total events. - To calculate average value: `A / B` where A is sum of property and B is count. ## Time interval Specify the time interval (group by time) using the `interval` field. Available intervals are: `hour`, `day`, `week`, `month`. Unless the user has specified otherwise, use the following default interval: - If the time period is less than two days, use the `hour` interval. - If the time period is less than a month, use the `day` interval. - If the time period is less than three months, use the `week` interval. - Otherwise, use the `month` interval. ## Breakdowns Breakdowns are used to segment data by property values of maximum three properties. They divide all defined trends series into multiple subseries based on the values of the property. Include breakdowns **only when they are essential to directly answer the user's question**. You should not add breakdowns if the question can be addressed without additional segmentation. Always use the minimum set of breakdowns needed. When using breakdowns, you should: - **Identify the property group** and name for each breakdown. - **Provide the property name** for each breakdown. - **Validate that the property value accurately reflects the intended criteria**. Examples of using breakdowns: - page views trend by country: you need to find a property such as `$geoip_country_code` and set it as a breakdown. - number of users who have completed onboarding by an organization: you need to find a property such as `organization name` and set it as a breakdown. # Examples ## How many users signed up? ```json { "kind": "TrendsQuery", "series": [{ "kind": "EventsNode", "event": "user signed up", "math": "total" }], "dateRange": { "date_from": "-30d" }, "interval": "month", "trendsFilter": { "display": "BoldNumber" } } ``` ## Page views by referring domain for the last month ```json { "kind": "TrendsQuery", "series": [{ "kind": "EventsNode", "event": "$pageview", "math": "total" }], "dateRange": { "date_from": "-30d" }, "interval": "day", "breakdownFilter": { "breakdowns": [{ "property": "$referring_domain", "type": "event" }] } } ``` ## DAU to MAU ratio for users from the US, compared to the previous period ```json { "kind": "TrendsQuery", "series": [ { "kind": "EventsNode", "event": "$pageview", "math": "dau" }, { "kind": "EventsNode", "event": "$pageview", "math": "monthly_active" } ], "dateRange": { "date_from": "-7d" }, "interval": "day", "properties": { "type": "AND", "values": [ { "type": "AND", "values": [{ "key": "$geoip_country_name", "operator": "exact", "type": "event", "value": ["United States"] }] } ] }, "compareFilter": { "compare": true }, "trendsFilter": { "display": "ActionsLineGraph", "formula": "A/B", "aggregationAxisFormat": "percentage_scaled" } } ``` ## Unique users and first-time users for "insight created" over the last 12 months ```json { "kind": "TrendsQuery", "series": [ { "kind": "EventsNode", "event": "insight created", "math": "dau" }, { "kind": "EventsNode", "event": "insight created", "math": "first_time_for_user" } ], "dateRange": { "date_from": "-12m" }, "interval": "month", "filterTestAccounts": true, "trendsFilter": { "display": "ActionsLineGraph" } } ``` ## P99, P95, and median of a "refreshAge" property on "viewed dashboard" events ```json { "kind": "TrendsQuery", "series": [ { "kind": "EventsNode", "event": "viewed dashboard", "math": "p99", "math_property": "refreshAge" }, { "kind": "EventsNode", "event": "viewed dashboard", "math": "p95", "math_property": "refreshAge" }, { "kind": "EventsNode", "event": "viewed dashboard", "math": "median", "math_property": "refreshAge" } ], "dateRange": { "date_from": "yStart" }, "interval": "month", "filterTestAccounts": true, "trendsFilter": { "display": "ActionsLineGraph", "aggregationAxisFormat": "duration" } } ``` ## Organizations that signed up from Google in the last 30 days (group aggregation) ```json { "kind": "TrendsQuery", "series": [ { "kind": "EventsNode", "event": "user signed up", "math": "unique_group", "math_group_type_index": 0, "properties": [{ "key": "is_organization_first_user", "operator": "exact", "type": "person", "value": ["true"] }] } ], "dateRange": { "date_from": "-30d" }, "interval": "day", "properties": { "type": "AND", "values": [ { "type": "OR", "values": [{ "key": "$initial_utm_source", "operator": "exact", "type": "person", "value": ["google"] }] } ] }, "trendsFilter": { "display": "ActionsLineGraph" } } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution. - When using group aggregations (unique groups), always set `math_group_type_index` to the appropriate group type index from the group mapping. - Visualization settings (display type, axis format, etc.) should only be specified when explicitly requested or when they significantly improve the answer.
Query Funnel
Run a funnel query to analyze conversion rates through a sequence of steps. Funnel insights help understand user behavior as users navigate through a product. A funnel consists of a sequence of at least two events or actions, where some users progress to the next step while others drop off. Funnels use percentages as the primary aggregation type. Use 'read-data-schema' to discover available events, actions, and properties for filters and breakdowns. IMPORTANT: Funnels REQUIRE AT LEAST TWO series (events or actions). The funnel insights have the following features: - Various visualization types (steps, time-to-convert, historical trends). - Filter data and apply exclusion steps (events only, not actions). - Break down data using a single property. - Specify conversion windows (default 14 days), step order (strict/ordered/unordered), and attribution settings. - Aggregate by users, sessions, or specific group types. - Track first-time conversions with special math aggregations. Examples of use cases include: - Conversion rates between steps. - Drop off steps (which step loses most users). - Steps with the highest friction and time to convert. - If product changes are improving their funnel over time. - Average/median/histogram of time to convert. - Conversion trends over time (using trends visualization type). - First-time user conversions (using first_time_for_user math). CRITICAL: Be minimalist. Only include filters, breakdowns, and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Funnel guidelines ## Exclusion steps Users may want to use exclusion events to filter out conversions in which a particular event occurred between specific steps. These events should not be included in the main sequence. You should include start and end indexes (0-based) for each exclusion where the minimum `funnelFromStep` is 0 (first step) and the maximum `funnelToStep` is the number of steps minus one. Exclusion events cannot be actions, only events. IMPORTANT: Exclusion steps filter out conversions where the exclusion event occurred BETWEEN the specified steps. This does NOT exclude users who completed the event before the funnel started or after it ended. For example, there is a sequence with three steps: sign up (step 0), finish onboarding (step 1), purchase (step 2). If the user wants to exclude all conversions in which users navigated away between sign up and finishing onboarding, the exclusion step will be `$pageleave` with `funnelFromStep: 0` and `funnelToStep: 1`. ## Breakdown A breakdown is used to segment data by a single property value. They divide all defined funnel series into multiple subseries based on the values of the property. Include a breakdown **only when it is essential to directly answer the user's question**. You should not add a breakdown if the question can be addressed without additional segmentation. When using breakdowns, you should: - **Identify the property group** and name for a breakdown. - **Provide the property name** for a breakdown. - **Validate that the property value accurately reflects the intended criteria**. Examples of using a breakdown: - page views to sign up funnel by country: you need to find a property such as `$geoip_country_code` and set it as a breakdown. - conversion rate of users who have completed onboarding after signing up by an organization: you need to find a property such as `organization name` and set it as a breakdown. # Examples ## Conversion from first event ingested to insight saved for organizations over 6 months ```json { "kind": "FunnelsQuery", "series": [ { "kind": "EventsNode", "event": "first team event ingested" }, { "kind": "EventsNode", "event": "insight saved" } ], "dateRange": { "date_from": "-6m" }, "interval": "month", "aggregation_group_type_index": 0, "funnelsFilter": { "funnelOrderType": "ordered", "funnelVizType": "trends", "funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day" }, "filterTestAccounts": true } ``` ## Signup page CTA click rate within one hour, excluding page leaves, broken down by OS ```json { "kind": "FunnelsQuery", "series": [ { "kind": "EventsNode", "event": "$pageview", "properties": [{ "key": "$current_url", "type": "event", "value": "signup", "operator": "icontains" }] }, { "kind": "EventsNode", "event": "click subscribe button", "properties": [{ "key": "$current_url", "type": "event", "value": "signup", "operator": "icontains" }] } ], "dateRange": { "date_from": "-180d" }, "interval": "week", "funnelsFilter": { "funnelWindowInterval": 1, "funnelWindowIntervalUnit": "hour", "funnelOrderType": "ordered", "exclusions": [{ "kind": "EventsNode", "event": "$pageleave", "funnelFromStep": 0, "funnelToStep": 1 }] }, "breakdownFilter": { "breakdown_type": "event", "breakdown": "$os" }, "filterTestAccounts": true } ``` ## Credit card purchase rate from viewing a product with strict ordering (no events in between) ```json { "kind": "FunnelsQuery", "series": [ { "kind": "EventsNode", "event": "view product" }, { "kind": "EventsNode", "event": "purchase", "properties": [{ "key": "paymentMethod", "type": "event", "value": "credit_card", "operator": "exact" }] } ], "dateRange": { "date_from": "-30d" }, "funnelsFilter": { "funnelOrderType": "strict", "funnelWindowInterval": 14, "funnelWindowIntervalUnit": "day" }, "filterTestAccounts": true } ``` ## View product to buy button to purchase, using actions and events ```json { "kind": "FunnelsQuery", "series": [ { "kind": "ActionsNode", "id": 8882, "name": "view product" }, { "kind": "EventsNode", "event": "click buy button" }, { "kind": "ActionsNode", "id": 573, "name": "purchase", "properties": [ { "key": "shipping_method", "value": "express_delivery", "operator": "icontains", "type": "event" } ] } ], "funnelsFilter": { "funnelVizType": "steps" }, "filterTestAccounts": true } ``` # Reminders - You MUST ALWAYS use AT LEAST TWO series (events or actions) in the funnel. - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution. - The default funnel step order is `ordered` (events in sequence but with other events allowed in between). Use `strict` when events should happen consecutively with no events in between. Use `unordered` when order doesn't matter. - Exclusion events in funnels only exclude conversions where the event happened between the specified steps, not before or after the funnel.
Query Retention
Run a retention query to analyze how many users return over time after performing an initial action. Retention insights show you how many users return during subsequent periods. They're useful for understanding user engagement and stickiness. Use 'read-data-schema' to discover available events, actions, and properties for filters. Examples of use cases include: - Are new sign ups coming back to use your product after trying it? - Have recent changes improved retention? - How many users come back and perform an action after their first visit. - How many users come back to perform action X after performing action Y. - How often users return to use a specific feature. CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Retention guidelines Retention insights always require two entities: - The activation event (targetEntity) – determines if the user is a part of a cohort (when they "start"). - The retention event (returningEntity) – determines whether a user has been retained (when they "return"). For activation and retention events, use the `$pageview` event by default or the equivalent for mobile apps `$screen`. Avoid infrequent or inconsistent events like `signed in` unless asked explicitly, as they skew the data. The activation and retention events can be the same (e.g., both `$pageview` to see if users who viewed pages come back to view pages again) or different (e.g., activation is `signed up` and retention is `completed purchase` to see if sign-ups convert to purchases over time). # Examples ## Weekly retention of users who created an insight ```json { "kind": "RetentionQuery", "retentionFilter": { "period": "Week", "totalIntervals": 9, "targetEntity": { "id": "insight created", "name": "insight created", "type": "events" }, "returningEntity": { "id": "insight created", "name": "insight created", "type": "events" }, "retentionType": "retention_first_time", "retentionReference": "total", "cumulative": false }, "filterTestAccounts": true } ``` ## Do users who sign up come back to view pages? ```json { "kind": "RetentionQuery", "retentionFilter": { "period": "Week", "totalIntervals": 8, "targetEntity": { "id": "user signed up", "name": "user signed up", "type": "events" }, "returningEntity": { "id": "$pageview", "name": "$pageview", "type": "events" }, "retentionType": "retention_first_time", "retentionReference": "total", "cumulative": false }, "dateRange": { "date_from": "-60d" }, "filterTestAccounts": true } ``` ## Daily retention of pageviews for mobile users only ```json { "kind": "RetentionQuery", "retentionFilter": { "period": "Day", "totalIntervals": 14, "targetEntity": { "id": "$pageview", "name": "$pageview", "type": "events" }, "returningEntity": { "id": "$pageview", "name": "$pageview", "type": "events" }, "retentionType": "retention_first_time", "retentionReference": "total", "cumulative": false }, "properties": [{ "key": "$os", "operator": "exact", "type": "event", "value": ["iOS", "Android"] }], "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution.
Query Stickiness
Run a stickiness query to measure how many intervals (e.g. days) within a date range users performed an event. Stickiness insights show user engagement intensity — the X-axis shows the number of intervals (1, 2, 3, ...) and the Y-axis shows how many users performed the event on exactly that many intervals. They're useful for understanding how deeply users engage with a feature. Use 'read-data-schema' to discover available events, actions, and properties for filters. Examples of use cases include: - How many days per week do users use a feature? - What percentage of users are power users (using the product every day)? - How engaged are users with a specific feature over the past month? - Compare stickiness of different features to find the most engaging one. - Has a product change improved user engagement frequency? CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Stickiness guidelines Stickiness insights measure engagement intensity — how many intervals (days, weeks, etc.) within a date range each user performed an event. Unlike trends which show event counts over time, stickiness shows the distribution of user engagement frequency. Key concepts: - The `interval` field determines what counts as one period. With `day` interval over a 30-day range, the chart shows how many users performed the event on 1 day, 2 days, 3 days, etc., up to 30 days. - When `math` is omitted on a series, stickiness counts unique persons by default. - Multiple series can be included to compare stickiness of different events side by side. - Stickiness does NOT support breakdowns. ## Aggregation The default aggregation for stickiness is unique persons. You can change how users are identified using the `math` field on each series: - `dau` or omit math — count unique persons (default behavior; both resolve to person_id aggregation) - `unique_group` — count unique groups (requires `math_group_type_index` to be set to the group type index from the group mapping) - `hogql` — custom HogQL expression (requires `math_hogql` to be set to a valid HogQL aggregation expression, e.g. `count(distinct properties.$session_id)`) ## Stickiness criteria Use `stickinessFilter.stickinessCriteria` to filter which intervals count based on event frequency within each interval. This applies a HAVING clause to the inner aggregation. - `operator` — one of `gte` (greater than or equal), `lte` (less than or equal), `exact` (exactly equal) - `value` — the threshold count For example, to only count intervals where the user performed the event at least 3 times, set `stickinessCriteria: { "operator": "gte", "value": 3 }`. ## Cumulative mode Use `stickinessFilter.computedAs` to change how stickiness is computed: - `non_cumulative` (default) — each bar shows users active on **exactly** N intervals - `cumulative` — each bar shows users active on **N or more** intervals ## Time interval Specify the time interval using the `interval` field. Available intervals are: `hour`, `day`, `week`, `month`. Unless the user has specified otherwise, use `day` as the default interval. Use `intervalCount` to group multiple base intervals into a single period. For example, `interval: "day"` with `intervalCount: 7` groups by 7-day periods. Defaults to 1. ## Compare Use `compareFilter` with `compare: true` to show the current and previous period side by side. # Examples ## How many days per week do users use pageview? ```json { "kind": "StickinessQuery", "series": [{ "kind": "EventsNode", "event": "$pageview" }], "dateRange": { "date_from": "-30d" }, "interval": "day", "filterTestAccounts": true } ``` ## Compare stickiness of two features ```json { "kind": "StickinessQuery", "series": [ { "kind": "EventsNode", "event": "insight created" }, { "kind": "EventsNode", "event": "dashboard viewed" } ], "dateRange": { "date_from": "-30d" }, "interval": "day", "filterTestAccounts": true } ``` ## Weekly stickiness for paid users, compared to previous period ```json { "kind": "StickinessQuery", "series": [{ "kind": "EventsNode", "event": "$pageview" }], "dateRange": { "date_from": "-90d" }, "interval": "week", "properties": [{ "key": "paidCustomer", "operator": "exact", "type": "person", "value": ["true"] }], "compareFilter": { "compare": true }, "filterTestAccounts": true } ``` ## Stickiness with criteria: only count days with 3+ events ```json { "kind": "StickinessQuery", "series": [{ "kind": "EventsNode", "event": "$pageview" }], "dateRange": { "date_from": "-30d" }, "interval": "day", "filterTestAccounts": true, "stickinessFilter": { "stickinessCriteria": { "operator": "gte", "value": 3 } } } ``` ## Cumulative stickiness: users active on N or more days ```json { "kind": "StickinessQuery", "series": [{ "kind": "EventsNode", "event": "feature used" }], "dateRange": { "date_from": "-30d" }, "interval": "day", "filterTestAccounts": true, "stickinessFilter": { "computedAs": "cumulative" } } ``` ## Organization-level stickiness for a feature ```json { "kind": "StickinessQuery", "series": [ { "kind": "EventsNode", "event": "feature used", "math": "unique_group", "math_group_type_index": 0 } ], "dateRange": { "date_from": "-30d" }, "interval": "day", "filterTestAccounts": true, "stickinessFilter": { "display": "ActionsBar" } } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution. - Stickiness does NOT support breakdowns — do not include a `breakdownFilter`. - When using group aggregations (unique groups), always set `math_group_type_index` to the appropriate group type index from the group mapping. - The default interval is `day` and the default math is unique persons — omit these unless the user asks for something different.
Query Paths
Run a paths query to analyze the most common sequences of events or pages that users navigate through. Paths insights visualize user flows as a directed graph, showing how users move between steps and where they drop off. Use 'read-data-schema' to discover available events, actions, and properties for filters. Examples of use cases include: - What do users do after signing up? - What pages do users visit before making a purchase? - What are the most common navigation flows on your website? - Where do users drop off in a particular flow? - What custom events lead to a conversion? CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Paths guidelines ## Event types Paths analyze sequences of events. Specify which event types to include using `includeEventTypes`. If omitted, all events are included without type filtering. - `$pageview` - web page views. Path values come from `$current_url`, with trailing slashes stripped, so they must match your stored URL format. This is often a path like `/login`, but may also be a full URL like `https://example.com/login`. Best for analyzing website navigation flows. This is the most common choice. - `$screen` - mobile screen views. Path values are screen names (from `$screen_name`). Use for mobile app navigation analysis. - `custom_event` - custom events (any event whose name does not start with `$`). Path values are event names. Use for analyzing flows of custom-tracked events like button clicks, form submissions, or feature usage. - `hogql` - custom HogQL expression. Use with `pathsHogQLExpression` for advanced path definitions. You can combine multiple types. For example, include both `$pageview` and `custom_event` to see how page views and custom events interleave. ## Start and end points Use `startPoint` to filter paths that begin at a specific step, or `endPoint` to filter paths that end at a specific step. The value format depends on the event type: - For `$pageview`: use the same URL format as your `$current_url` values, often paths like `/login`, `/dashboard`, `/settings`, but sometimes full URLs - For `$screen`: use screen names - For `custom_event`: use event names like `user signed up`, `purchase completed` ## Path cleaning Use `localPathCleaningFilters` to normalize dynamic URLs. Each filter has a `regex` pattern (ClickHouse regex syntax) and an `alias` replacement. Filters are applied in sequence using `replaceRegexpAll(path, regex, alias)`. For example, to normalize product URLs: `{ "regex": "\\/product\\/\\d+", "alias": "/product/:id" }`. Use `pathGroupings` for simpler glob-like grouping of paths into single nodes. Use `*` as a wildcard — the patterns are auto-escaped so only `*` has special meaning. For example, `/product/*` groups all product sub-pages into one node. ## Exclusions Use `excludeEvents` to remove specific path items that clutter the visualization. The values must match path item values, not event types: for `$pageview` paths these must match your stored `$current_url` format (e.g., `/health-check` or `https://example.com/health-check`), for `custom_event` paths these are event names (e.g., `heartbeat`). To control which event types are included, use `includeEventTypes` instead. # Examples ## What pages do users visit after the homepage? ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["$pageview"], "startPoint": "/", "stepLimit": 5 }, "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true } ``` ## What do users do after signing up? ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["custom_event"], "startPoint": "user signed up", "stepLimit": 5 }, "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true } ``` ## Navigation paths excluding noisy URLs ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["$pageview"], "excludeEvents": ["/health-check", "/ping"], "stepLimit": 5, "edgeLimit": 30 }, "dateRange": { "date_from": "-14d" }, "filterTestAccounts": true } ``` ## Custom event paths excluding noisy events ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["custom_event"], "excludeEvents": ["heartbeat"], "stepLimit": 5 }, "dateRange": { "date_from": "-14d" }, "filterTestAccounts": true } ``` ## Paths with URL cleaning for dynamic segments ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["$pageview"], "stepLimit": 5, "localPathCleaningFilters": [ { "regex": "\\/user\\/\\d+", "alias": "/user/:id" }, { "regex": "\\/project\\/[a-f0-9-]+", "alias": "/project/:id" } ] }, "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true } ``` ## What paths lead to the pricing page for mobile users? ```json { "kind": "PathsQuery", "pathsFilter": { "includeEventTypes": ["$pageview"], "endPoint": "/pricing", "stepLimit": 5 }, "properties": [{ "key": "$os", "operator": "exact", "type": "event", "value": ["iOS", "Android"] }], "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution. - Always specify `includeEventTypes` to scope the analysis to relevant event types. If omitted, all events are included which may produce noisy results. - Use `$pageview` as the default event type for web navigation questions. - Path cleaning filters (`localPathCleaningFilters`) use ClickHouse regex and are only needed when dynamic URL segments would fragment the visualization. Path groupings (`pathGroupings`) use glob-like patterns with `*` wildcards for simpler cases. - Paths group events into sessions with a 30-minute inactivity threshold — events more than 30 minutes apart start a new path session.
Query Lifecycle
Run a lifecycle query to categorize users into lifecycle stages based on their activity pattern relative to a single event or action. Lifecycle insights break users into four mutually exclusive groups for each time period: new, returning, resurrecting, and dormant. They're useful for understanding the composition of your active users and diagnosing growth or churn patterns. Use 'read-data-schema' to discover available events, actions, and properties for filters. Examples of use cases include: - What is the composition of my active users over time? - Are we gaining new users faster than we're losing dormant ones? - How many users resurrected (came back after being inactive) last week? - Is the returning user base growing or shrinking? - How does user engagement change after a product launch? CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Avoid using properties for identification like IDs. Instead, prioritize filtering based on general properties like `paidCustomer` or `icp_score`. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. - You set logical operators to combine multiple properties of a single series: AND or OR. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 30 days as a default time period. # Lifecycle guidelines Lifecycle insights analyze a **single event or action** over time. The `series` array must contain exactly one item. If the user mentions multiple events, pick the most relevant one or clarify. ## Lifecycle statuses Each user is categorized into one of four statuses for each time period: - **New** – the user performed the event for the first time ever during this period. - **Returning** – the user was active in the previous period and is active again in the current period. - **Resurrecting** – the user was inactive for one or more periods and became active again. - **Dormant** – the user was active in the previous period but did not perform the event in the current period. Dormant counts are shown as negative values. ## Time interval Specify the time interval using the `interval` field. Available intervals are: `hour`, `day`, `week`, `month`. The default is `day`. Unless the user has specified otherwise, use the following default interval: - If the time period is less than two days, use the `hour` interval. - If the time period is less than a month, use the `day` interval. - If the time period is less than three months, use the `week` interval. - Otherwise, use the `month` interval. ## Toggled lifecycles Use `toggledLifecycles` in `lifecycleFilter` to control which lifecycle statuses are displayed. By default, all four statuses are shown. Only set this when the user wants to focus on specific statuses (e.g., only new and dormant users). ## Math aggregation Lifecycle insights do **not** support math aggregation types. Do not set `math` on the series node. # Examples ## Daily lifecycle of pageviews over the last 30 days ```json { "kind": "LifecycleQuery", "series": [{ "kind": "EventsNode", "event": "$pageview" }], "dateRange": { "date_from": "-30d" }, "interval": "day" } ``` ## Weekly lifecycle of sign ups, excluding test accounts ```json { "kind": "LifecycleQuery", "series": [{ "kind": "EventsNode", "event": "user signed up" }], "dateRange": { "date_from": "-90d" }, "interval": "week", "filterTestAccounts": true } ``` ## Monthly lifecycle of "insight created" showing only new and dormant users ```json { "kind": "LifecycleQuery", "series": [{ "kind": "EventsNode", "event": "insight created" }], "dateRange": { "date_from": "-12m" }, "interval": "month", "lifecycleFilter": { "toggledLifecycles": ["new", "dormant"] }, "filterTestAccounts": true } ``` ## Lifecycle of purchases by mobile users ```json { "kind": "LifecycleQuery", "series": [{ "kind": "EventsNode", "event": "purchase completed" }], "dateRange": { "date_from": "-30d" }, "interval": "day", "properties": [{ "key": "$os", "operator": "exact", "type": "event", "value": ["iOS", "Android"] }] } ``` # Reminders - Lifecycle insights support only **one** series — do not add multiple events or actions. - Do not set `math` on the series node — lifecycle does not support math aggregation. - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution.
Query Llm Traces List
List LLM traces to inspect AI/LLM usage across your application. Returns traces with their events, latency, token usage, costs, errors, and other metadata. Use this tool for AI observability — debugging slow generations, investigating errors, analyzing token spend, and auditing LLM behavior. Use 'read-data-schema' to discover available event properties for filtering (e.g. `$ai_model`, `$ai_provider`). Examples of use cases include: - How much are we spending on LLM tokens per day? - Which LLM generations are the slowest? - Are there any traces with errors in the last 24 hours? - What models are being used and how do their costs compare? - Show me traces for a specific user to debug their experience. - Are there any traces with unusually high token usage? CRITICAL: Be minimalist. Only include filters and settings that are essential to answer the user's specific question. Default settings are usually sufficient unless the user explicitly requests customization. # Data narrowing ## Property filters Use property filters to narrow results. Only include property filters when they are essential to directly answer the user's question. Avoid adding them if the question can be addressed without additional segmentation and always use the minimum set of property filters needed. IMPORTANT: Do not check if a property is set unless the user explicitly asks for it. When using a property filter, you should: - **Prioritize properties directly related to the context or objective of the user's query.** Common AI properties include `$ai_model`, `$ai_provider`, `$ai_trace_id`, `$ai_session_id`, `$ai_latency`, `$ai_input_tokens`, `$ai_output_tokens`, `$ai_total_cost_usd`, `$ai_is_error`, `$ai_http_status`, `$ai_span_name`. - **Note:** `$ai_is_error` and `$ai_error` are valid filter properties but may not appear via `read-data-schema`. Use `$ai_is_error` with operator `exact` and value `["true"]` to find error traces, or use `$ai_error` with `is set` to find traces with error messages. - **Ensure that you find both the property group and name.** Property groups should be one of the following: event, person, session, group. - After selecting a property, **validate that the property value accurately reflects the intended criteria**. - **Find the suitable operator for type** (e.g., `contains`, `is set`). - If the operator requires a value, use the `read-data-schema` tool to find the property values. Infer the property groups from the user's request. If your first guess doesn't yield any results, try to adjust the property group. Supported operators for the String type are: - equals (exact) - doesn't equal (is_not) - contains (icontains) - doesn't contain (not_icontains) - matches regex (regex) - doesn't match regex (not_regex) - is set - is not set Supported operators for the Numeric type are: - equals (exact) - doesn't equal (is_not) - greater than (gt) - less than (lt) - is set - is not set Supported operators for the DateTime type are: - equals (is_date_exact) - doesn't equal (is_not for existence check) - before (is_date_before) - after (is_date_after) - is set - is not set Supported operators for the Boolean type are: - equals - doesn't equal - is set - is not set All operators take a single value except for `equals` and `doesn't equal` which can take one or more values (as an array). ## Time period You should not filter events by time using property filters. Instead, use the `dateRange` field. If the question doesn't mention time, use last 7 days as a default time period. # Traces guidelines This is a listing tool, not a visualization/insight tool. It returns a paginated list of LLM traces — it does NOT support series, breakdowns, math aggregations, or chart types. ## Response shape Each trace in the results contains: - `id` — unique trace ID - `traceName` — name of the trace (if set via SDK) - `createdAt` — timestamp of the first event in the trace - `distinctId` — the person's distinct ID - `aiSessionId` — session ID grouping related traces (e.g., a conversation) - `totalLatency` — total latency in seconds - `inputTokens` / `outputTokens` — token counts across all generations in the trace - `inputCost` / `outputCost` / `totalCost` — costs in USD - `inputState` / `outputState` — JSON input/output state of the trace (e.g., conversation messages), from the `$ai_trace` event - `errorCount` — number of errors in the trace - `isSupportTrace` — whether the trace was from a support impersonation session - `tools` — list of tool names called during the trace - `events` — list of direct child events (generations, metrics, feedback). Each event's `properties` contains the full event data — see "Event types and their properties" below. ## Event types and their properties Each event in `events` has an `event` field indicating its type. The key properties vary by type: - **`$ai_generation`** / **`$ai_embedding`** — an LLM or embedding API call. Properties include `$ai_input` (input prompt JSON), `$ai_output_choices` (output message JSON), `$ai_model`, `$ai_provider`, `$ai_latency`, `$ai_input_tokens`, `$ai_output_tokens`, `$ai_input_cost_usd`, `$ai_output_cost_usd`, `$ai_total_cost_usd`, `$ai_tools_called`, `$ai_is_error`, `$ai_error`. - **`$ai_span`** — a unit of work within a trace (e.g., a retrieval step, a tool execution). Properties include `$ai_input_state`, `$ai_output_state`, `$ai_latency`, `$ai_span_name`, `$ai_parent_id`. - **`$ai_trace`** — the root trace event. Properties include `$ai_input_state` (e.g., conversation messages sent), `$ai_output_state` (e.g., final response), `$ai_span_name`. - **`$ai_metric`** — a named evaluation metric. Properties include `$ai_metric_name`, `$ai_metric_value`. - **`$ai_feedback`** — user-provided feedback. Properties include `$ai_feedback_text`. All event types share `$ai_trace_id`, `$ai_span_id`, and `$ai_parent_id` for tree structure (see below). ## Tree structure (IDs and parent-child relationships) Events in a trace form a tree. Each event carries three IDs that define its position: - `$ai_trace_id` — present on every event, identifies which trace it belongs to (same as the trace's `id`) - `$ai_span_id` (or `$ai_generation_id` for generations) — the event's own unique identifier - `$ai_parent_id` — points to the parent event's `$ai_span_id` To reconstruct the tree: 1. Events where `$ai_parent_id` equals `$ai_trace_id` are **root-level children** of the trace 2. Other events are children of the event whose `$ai_span_id` matches their `$ai_parent_id` 3. Group events by `$ai_parent_id` and walk from root children downward Generations (`$ai_generation`) and embeddings (`$ai_embedding`) are always leaf nodes. Spans (`$ai_span`) can have children. **Important:** This list tool only returns **direct children** of the trace (events where `$ai_parent_id` = trace ID) plus all `$ai_metric` and `$ai_feedback` events — NOT deeply nested events. For the full event tree with all nested children, use `query-llm-trace` with the trace's `id`. ## Pagination Use `limit` and `offset` for pagination. The default limit is 100. The response includes a `hasMore` field indicating whether more results are available. ## Filtering - `filterTestAccounts` — exclude internal/test users - `filterSupportTraces` — exclude support impersonation traces - `personId` — filter by a specific person UUID - `groupKey` + `groupTypeIndex` — filter by a specific group - `randomOrder` — use random ordering instead of newest-first (useful for representative sampling) # Examples ## Recent traces with errors ```json { "kind": "TracesQuery", "dateRange": { "date_from": "-7d" }, "filterTestAccounts": true, "properties": [{ "key": "$ai_is_error", "operator": "exact", "type": "event", "value": ["true"] }], "limit": 50 } ``` ## Traces for a specific model ```json { "kind": "TracesQuery", "dateRange": { "date_from": "-7d" }, "filterTestAccounts": true, "properties": [{ "key": "$ai_model", "operator": "exact", "type": "event", "value": ["gpt-4o"] }] } ``` ## Traces for a specific person ```json { "kind": "TracesQuery", "dateRange": { "date_from": "-30d" }, "personId": "01234567-89ab-cdef-0123-456789abcdef", "filterTestAccounts": true } ``` ## Random sample of traces (avoids recency bias) ```json { "kind": "TracesQuery", "dateRange": { "date_from": "-30d" }, "filterTestAccounts": true, "randomOrder": true, "limit": 20 } ``` # Reminders - Ensure that any properties included are directly relevant to the context and objectives of the user's question. Avoid unnecessary or unrelated details. - Avoid overcomplicating the response with excessive property filters. Focus on the simplest solution. - This tool returns raw trace data — it does not aggregate or visualize. For aggregated LLM metrics over time (e.g. total token usage per day), use `query-trends` with AI events like `$ai_generation` instead. - Use `filterTestAccounts: true` by default to exclude internal users unless the user asks otherwise. - The default time range is last 7 days. LLM trace data tends to be recent, so shorter ranges are usually appropriate. - For deep inspection of a single trace (full event tree with all nested children and complete properties), use `query-llm-trace` with the trace's `id`.
Query Llm Trace
Fetch a single LLM trace by its trace ID for deep inspection. Returns the complete trace with all nested events and their full properties — including inputs, outputs, model parameters, costs, and errors. Use after finding a trace via `query-llm-traces-list` to inspect the complete event tree. Use cases: - Inspect the full input/output of each generation in a trace - Debug a specific error trace found in the list - Examine the agent's decision-making flow across spans - Review tool calls and their results within a trace - Analyze token usage and costs per generation CRITICAL: This tool requires a `traceId`. Get the trace ID from `query-llm-traces-list` results first. # Response shape The response contains a single trace in JSON format with: - `id` — the trace ID - `traceName` — name of the trace (if set via SDK) - `createdAt` — timestamp of the first event in the trace - `distinctId` — the person's distinct ID - `aiSessionId` — session ID grouping related traces (e.g., a conversation) - `totalLatency` — total latency in seconds - `inputTokens` / `outputTokens` — token counts across all generations - `inputCost` / `outputCost` / `totalCost` — costs in USD - `inputState` / `outputState` — JSON input/output state from the root `$ai_trace` event (e.g., conversation messages) - `events` — **all** child events in the trace at every nesting depth (not just direct children). Each event has full `properties`. Unlike `query-llm-traces-list`, this tool does NOT return `errorCount`, `isSupportTrace`, or `tools` — those are summary fields on the list tool only. # Event types and their properties Each event in `events` has an `event` field indicating its type. Key properties vary by type: - **`$ai_generation`** / **`$ai_embedding`** — an LLM or embedding API call. Properties include `$ai_input` (input prompt JSON), `$ai_output_choices` (output message JSON), `$ai_model`, `$ai_provider`, `$ai_latency`, `$ai_input_tokens`, `$ai_output_tokens`, `$ai_input_cost_usd`, `$ai_output_cost_usd`, `$ai_total_cost_usd`, `$ai_tools_called`, `$ai_is_error`, `$ai_error`. - **`$ai_span`** — a unit of work within a trace (e.g., a retrieval step, tool execution). Properties include `$ai_input_state`, `$ai_output_state`, `$ai_latency`, `$ai_span_name`, `$ai_parent_id`. - **`$ai_metric`** — a named evaluation metric. Properties include `$ai_metric_name`, `$ai_metric_value`. - **`$ai_feedback`** — user-provided feedback. Properties include `$ai_feedback_text`. Note: `$ai_trace` events are NOT included in the `events` array — their data is surfaced via the trace-level `inputState`, `outputState`, and `traceName` fields. # Tree structure (IDs and parent-child relationships) Events in a trace form a tree. Each event carries three IDs that define its position: - `$ai_trace_id` — present on every event, identifies which trace it belongs to (same as the trace's `id`) - `$ai_span_id` (or `$ai_generation_id` for generations) — the event's own unique identifier - `$ai_parent_id` — points to the parent event's `$ai_span_id` To reconstruct the tree: 1. Events where `$ai_parent_id` equals `$ai_trace_id` are **root-level children** of the trace 2. Other events are children of the event whose `$ai_span_id` matches their `$ai_parent_id` 3. Group events by `$ai_parent_id` and walk from root children downward Generations (`$ai_generation`) and embeddings (`$ai_embedding`) are always leaf nodes. Spans (`$ai_span`) can have children. # Examples ## Fetch a trace by ID ```json { "kind": "TraceQuery", "traceId": "c9222e05-8708-41b8-98ea-d4a21849e761" } ``` ## Fetch with a date range hint If the trace is old, provide a date range to help the query find it efficiently: ```json { "kind": "TraceQuery", "traceId": "c9222e05-8708-41b8-98ea-d4a21849e761", "dateRange": { "date_from": "-30d" } } ``` # Reminders - Always get the `traceId` from `query-llm-traces-list` results — do not guess or fabricate trace IDs. - If no date range is provided, the default lookback window is used. For older traces, provide an explicit `dateRange`. - The `events` array contains ALL events in the trace (including deeply nested ones), making this suitable for full tree reconstruction. - Use `query-llm-traces-list` first to find traces, then this tool to inspect a specific one.
GAIA connects to PostHog via MCP (Model Context Protocol) and exposes every action as a natural-language command. Tell GAIA what you want — it handles the rest, automatically.
Set up your PostHog automation in three simple steps — no code required.
Connect PostHog to GAIA
Open the GAIA Marketplace, find the PostHog integration, and click "Add to your GAIA". Authorise access in under two minutes — no code, no configuration files.
Tell GAIA what to automate in plain English
Describe the task in your own words: "summarise my PostHog activity every morning" or "notify me on Slack when a new business event happens". GAIA understands context and intent.
GAIA handles it automatically, 24/7
GAIA runs your PostHog automations in the background around the clock. No manual triggers, no scripts to maintain — just results delivered to you.
Everything you need to know about the GAIA PostHog integration.
PostHog is just one piece of the puzzle. GAIA integrates with 50+ tools across business, communication, productivity, and more — letting you build cross-tool automations in plain English without writing a single line of code.
Browse all integrations