---
title: "Get a person's properties timeline for an insight data point"
method: POST
path: "/api/projects/{project_id}/persons/{id}/properties_timeline/"
tags: ["persons"]
---

# Get a person's properties timeline for an insight data point

`POST /api/projects/{project_id}/persons/{id}/properties_timeline/`

## Request

- Base URL: `https://us.posthog.com`
- URL: `https://us.posthog.com/api/projects/{project_id}/persons/{id}/properties_timeline/`
- Auth: HTTP bearer

Shows how the person's key properties changed within the time window of a Trends data point. The key properties are the person properties that the insight's query uses.

## Path parameters

- `id` string, required
- `project_id` string, required

## Query parameters

- `format` 'csv' | 'json'

## Request body

- PropertiesTimelineRequest
  - `query` InsightActorsQuery, required
    - `breakdown` union
      - string
      - string[]
      - integer
    - `compare` 'current' | 'previous'
    - `day` union
      - string
      - integer
    - `includeRecordings` boolean, nullable
    - `interval` integer, nullable: An interval selected out of available intervals in source query.
    - `kind` 'InsightActorsQuery'
    - `modifiers` HogQLQueryModifiers
      - `bounceRateDurationSeconds` number, nullable
      - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
      - `convertToProjectTimezone` boolean, nullable
      - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
      - `customBotDefinitions` CustomBotRule[], nullable
        - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
        - `combiner` 'AND' | 'OR', required
        - `id` string, required
        - `items` CustomBotCondition[], required
          - `id` string, required
          - `key` '$raw_user_agent' | '$ip' | '$lib' | '$host' | '$pathname' | '$current_url' | '$browser' | '$os' | '$browser_language' | '$screen_width' | '$screen_height' | '$geoip_country_code' | '$referrer' | '$referring_domain', required
          - `matcher` 'contains' | 'regex' | 'exact' | 'cidr', required
          - `pattern` string, required: Matched against the property named by `key`.
        - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
      - `customChannelTypeRules` CustomChannelRule[], nullable
        - `channel_type` string, required
        - `combiner` 'AND' | 'OR', required
        - `id` string, required
        - `items` CustomChannelCondition[], required
          - `id` string, required
          - `key` 'utm_source' | 'utm_medium' | 'utm_campaign' | 'referring_domain' | 'url' | 'pathname' | 'hostname', required
          - `op` 'exact' | 'is_not' | 'is_set' | 'is_not_set' | 'icontains' | 'not_icontains' | 'regex' | 'not_regex', required
          - `value` union
            - string
            - string[]
      - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
        - `distinct_id_field` string, required
        - `id_field` string, required
        - `table_name` string, required
        - `timestamp_field` string, required
      - `debug` boolean, nullable
      - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
      - `formatCsvAllowDoubleQuotes` boolean, nullable
      - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
      - `inlineCohortCalculation` 'off' | 'auto' | 'always'
      - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
      - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
      - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
      - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
      - `optimizeJoinedFilters` boolean, nullable
      - `optimizeProjections` boolean, nullable
      - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
      - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
      - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
      - `personsJoinMode` 'inner' | 'left'
      - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
      - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
      - `pushDownPredicates` boolean, nullable
      - `s3TableUseInvalidColumns` boolean, nullable
      - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
      - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
      - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
      - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
      - `sessionsV2JoinMode` 'string' | 'uuid'
      - `timings` boolean, nullable
      - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
      - `useMaterializedViews` boolean, nullable
      - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
      - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
      - `usePreaggregatedIntermediateResults` boolean, nullable
      - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
      - `useWebAnalyticsPreAggregatedTables` boolean, nullable
      - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
    - `response` ActorsQueryResponse
      - `columns` unknown[], required
        - unknown
      - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
      - `hasMore` boolean, nullable
      - `hogql` string, required: Generated HogQL query.
      - `limit` integer, required
      - `missing_actors_count` integer, nullable
      - `modifiers` HogQLQueryModifiers
        - `bounceRateDurationSeconds` number, nullable
        - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
        - `convertToProjectTimezone` boolean, nullable
        - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
        - `customBotDefinitions` CustomBotRule[], nullable
          - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
          - `combiner` 'AND' | 'OR', required
          - `id` string, required
          - `items` CustomBotCondition[], required
            - `id` string, required
            - `key` '$raw_user_agent' | '$ip' | '$lib' | '$host' | '$pathname' | '$current_url' | '$browser' | '$os' | '$browser_language' | '$screen_width' | '$screen_height' | '$geoip_country_code' | '$referrer' | '$referring_domain', required
            - `matcher` 'contains' | 'regex' | 'exact' | 'cidr', required
            - `pattern` string, required: Matched against the property named by `key`.
          - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
        - `customChannelTypeRules` CustomChannelRule[], nullable
          - `channel_type` string, required
          - `combiner` 'AND' | 'OR', required
          - `id` string, required
          - `items` CustomChannelCondition[], required
            - `id` string, required
            - `key` 'utm_source' | 'utm_medium' | 'utm_campaign' | 'referring_domain' | 'url' | 'pathname' | 'hostname', required
            - `op` 'exact' | 'is_not' | 'is_set' | 'is_not_set' | 'icontains' | 'not_icontains' | 'regex' | 'not_regex', required
            - `value` union
              - …
        - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
          - `distinct_id_field` string, required
          - `id_field` string, required
          - `table_name` string, required
          - `timestamp_field` string, required
        - `debug` boolean, nullable
        - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
        - `formatCsvAllowDoubleQuotes` boolean, nullable
        - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
        - `inlineCohortCalculation` 'off' | 'auto' | 'always'
        - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
        - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
        - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
        - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
        - `optimizeJoinedFilters` boolean, nullable
        - `optimizeProjections` boolean, nullable
        - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
        - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
        - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
        - `personsJoinMode` 'inner' | 'left'
        - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
        - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
        - `pushDownPredicates` boolean, nullable
        - `s3TableUseInvalidColumns` boolean, nullable
        - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
        - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
        - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
        - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
        - `sessionsV2JoinMode` 'string' | 'uuid'
        - `timings` boolean, nullable
        - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
        - `useMaterializedViews` boolean, nullable
        - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
        - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
        - `usePreaggregatedIntermediateResults` boolean, nullable
        - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
        - `useWebAnalyticsPreAggregatedTables` boolean, nullable
        - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
      - `offset` integer, required
      - `query_status` QueryStatus
        - `budget_remaining_bytes` integer, nullable
        - `bytes_read` integer, nullable
        - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
        - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
        - `dashboard_id` integer, nullable
        - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
        - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
        - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
        - `error_message` string, nullable
        - `expiration_time` string, date-time, nullable
        - `id` string, required
        - `insight_id` integer, nullable
        - `labels` string[], nullable
        - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
        - `query_async` true: ONLY async queries use QueryStatus.
        - `query_progress` ClickhouseQueryProgress
          - `active_cpu_time` integer, required
          - `bytes_read` integer, required
          - `estimated_rows_total` integer, required
          - `rows_read` integer, required
          - `time_elapsed` integer, required
        - `query_scan` QueryScanSummary
          - `analysis` QueryScanAnalysis
            - `assistant_prompt` string, nullable: The message the Fix with AI button sends to the assistant. Absent when no finding can be fixed in the query.
            - `findings` QueryScanWarning[], required: Every finding, fixable or not. Empty when the analysis found none.
              - …
            - `project_share` number, nullable: How much of all the project's events the query read, 0 to 1.
            - `range_share` number, nullable: How much of the project's events in the query's date range the query read, 0 to 1.
          - `analysis_requested` boolean, nullable: True when the run asked for an analysis, or found one stored. While `analysis` is absent, poll `GET /query/scan/{cache_key}` for it.
          - `duration_ms` integer, required: ClickHouse time for the last fresh run, summed over its ClickHouse queries.
          - `killed` boolean, nullable: True when ClickHouse stopped the run instead of finishing it.
          - `rows_read` integer, required: Rows ClickHouse read for the last fresh run, all tables included.
        - `results` unknown
        - `start_time` string, date-time, nullable: When was query execution task enqueued.
        - `task_id` string, nullable
        - `team_id` integer, required
      - `resolved_compare_date_range` ResolvedDateRangeResponse
        - `date_from` string, date-time, required
        - `date_to` string, date-time, required
      - `resolved_date_range` ResolvedDateRangeResponse
        - `date_from` string, date-time, required
        - `date_to` string, date-time, required
      - `results` array[], required
        - unknown[]
          - unknown
      - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
        - `k` string, required: Key. Shortened to 'k' to save on data.
        - `t` number, required: Time in seconds. Shortened to 't' to save on data.
      - `types` string[], nullable
      - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
        - `id` string, required: ExternalDataSource id
        - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
        - `table_name` string, required: Warehouse table name that was referenced
      - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
        - union
          - DataWarehouseSyncWarning
            - `data_is_current` boolean, nullable: True when the last sync is still within the table's sync interval, so the data is current and the warning only says it will stop updating (a sync paused recently). False or absent when the data is out of date.
            - `message` string, required: Human-readable warning shown to the user
            - `schema_name` string, required: Name of the ExternalDataSchema responsible for syncing the table
            - `source_id` string, nullable: ID of the ExternalDataSource, used to link to its management page. Null for self-managed tables.
            - `source_type` string, required: Source type, e.g. "Stripe", "Hubspot"
            - `status` string, required: Sync status that triggered the warning, e.g. "Failed", "Paused", "BillingLimitReached"
            - `table_name` string, required: Name of the warehouse table the warning refers to
            - `type` 'warehouse_sync': Tells warning kinds apart in the shared `warnings` list
          - AccessControlFilterWarning
            - `message` string, required: Human-readable warning shown to the user
            - `resources` string[], required: Resource types the user has access restrictions on, referenced by the query, e.g. ["insight", "dashboard"]
            - `type` 'access_control': Tells warning kinds apart in the shared `warnings` list
    - `series` integer, nullable
    - `source` union, required
      - TrendsQuery
        - `aggregation_group_type_index` integer, nullable: Groups aggregation
        - `breakdownFilter` BreakdownFilter
          - `breakdown` union
            - string
            - union[]
              - …
            - integer
          - `breakdown_group_type_index` integer, nullable
          - `breakdown_hide_other_aggregation` boolean, nullable
          - `breakdown_histogram_bin_count` integer, nullable
          - `breakdown_limit` integer, nullable
          - `breakdown_normalize_url` boolean, nullable
          - `breakdown_path_cleaning` boolean, nullable
          - `breakdown_type` 'cohort' | 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'data_warehouse' | 'data_warehouse_person_property' | 'revenue_analytics'
          - `breakdowns` Breakdown[], nullable
            - `group_type_index` integer, nullable
            - `histogram_bin_count` integer, nullable
            - `normalize_url` boolean, nullable
            - `property` union, required
              - …
            - `type` 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'cohort' | 'revenue_analytics' | 'data_warehouse' | 'data_warehouse_person_property'
        - `calendarHeatmapFilter` CalendarHeatmapFilter
          - `bucketBySessionStart` boolean, nullable: When true and the series math is `dau`/`unique_users`, each user contributes to the (day-of-week, hour) bucket of their session's first event only — matching the web overview session-start attribution. When false (default), the user contributes to every bucket they have any event in. No effect on `total` math (event counts are unchanged either way).
        - `compareFilter` CompareFilter
          - `compare` boolean, nullable: Whether to compare the current date range to a previous date range.
          - `compare_to` string, nullable: The date range to compare to. The value is a relative date. Examples of relative dates are: `-1y` for 1 year ago, `-14m` for 14 months ago, `-100w` for 100 weeks ago, `-14d` for 14 days ago, `-30h` for 30 hours ago.
        - `conversionGoal` union: Whether we should be comparing against a specific conversion goal
          - ActionConversionGoal
            - `actionId` integer, required
            - `properties` union[], nullable
              - …
          - CustomEventConversionGoal
            - `customEventName` string, required
            - `properties` union[], nullable
              - …
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `interval` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
        - `kind` 'TrendsQuery'
        - `marketingAnalyticsCostFallback` MarketingAnalyticsCostFallback
          - `series` DataWarehouseNode[], required
            - `custom_name` string, nullable
            - `distinct_id_field` string, required
            - `dw_source_type` string, nullable
            - `fixedProperties` union[], nullable: Fixed properties in the query, can't be edited in the interface (e.g. scoping down by person)
              - …
            - `id` string, required
            - `id_field` string, required
            - `kind` 'DataWarehouseNode'
            - `math` union
              - …
            - `math_group_type_index` 0 | 1 | 2 | 3 | 4
            - `math_hogql` string, nullable
            - `math_multiplier` number, nullable
            - `math_property` string, nullable
            - `math_property_revenue_currency` RevenueCurrencyPropertyConfig
              - …
            - `math_property_type` string, nullable
            - `name` string, nullable
            - `optionalInFunnel` boolean, nullable
            - `properties` union[], nullable: Properties configurable in the interface
              - …
            - `response` object, nullable
            - `table_name` string, required
            - `timestamp_field` string, required
            - `version` number, nullable: version of the node, used for schema migrations
          - `sourceIds` string[], required
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` TrendsQueryResponse
          - `boxplot_data` BoxPlotDatum[], nullable
            - `day` string, required
            - `label` string, required
            - `max` number, required
            - `mean` number, required
            - `median` number, required
            - `min` number, required
            - `p25` number, required
            - `p75` number, required
            - `series_index` integer, nullable
            - `series_label` string, nullable
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hasMore` boolean, nullable: Wether more breakdown values are available.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` object[], required
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `samplingFactor` number, nullable: Sampling rate
        - `series` union[], required: Events and actions to include
          - union
            - EventsNode
              - …
            - ActionsNode
              - …
            - DataWarehouseNode
              - …
            - GroupNode
              - …
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `trendsFilter` TrendsFilter
          - `aggregationAxisFormat` 'numeric' | 'duration' | 'duration_ms' | 'duration_ns' | 'percentage' | 'percentage_scaled' | 'currency' | 'short'
          - `aggregationAxisPostfix` string, nullable: Literal suffix applied to every value (e.g. ` req`). Reserve for units that `aggregationAxisFormat` cannot express. Do not use ` mins`, ` s`, ` ms`, `%` etc. — pick the matching `aggregationAxisFormat` instead so the underlying values stay numerically correct for breakdowns, formulas, and alerts. Include any leading space yourself.
          - `aggregationAxisPrefix` string, nullable: Literal prefix applied to every value (e.g. `$`). Use to pin a unit or currency symbol that does not depend on `aggregationAxisFormat` — for example, when values are denominated in a fixed currency regardless of the project's base currency. Include any trailing space yourself.
          - `annotationsScope` 'dashboard_item' | 'dashboard' | 'project' | 'organization'
          - `breakdown_histogram_bin_count` number, nullable
          - `chartStyle` ChartStyle
            - `curve` 'linear' | 'smooth'
            - `seriesColorMode` 'palette' | 'opacity'
          - `confidenceLevel` number, nullable
          - `decimalPlaces` number, nullable: Maximum number of decimal places shown. 1 or 2 is usually right for percentages and currency.
          - `detailedResultsAggregationType` 'total' | 'average' | 'median'
          - `display` 'Auto' | 'ActionsLineGraph' | 'ActionsBar' | 'ActionsUnstackedBar' | 'ActionsStackedBar' | 'ActionsAreaGraph' | 'ActionsLineGraphCumulative' | 'BoldNumber' | 'Metric' | 'ActionsPie' | 'ActionsDonut' | 'ActionsProportionBar' | 'ActionsBarValue' | 'ActionsTable' | 'WorldMap' | 'CalendarHeatmap' | 'TwoDimensionalHeatmap' | 'BoxPlot' | 'SlopeGraph' | 'ScatterPlot'
          - `excludeBoxPlotOutliers` boolean, nullable
          - `formula` string, nullable
          - `formulaNodes` TrendsFormulaNode[], nullable: List of formulas with optional custom names. Takes precedence over formula/formulas if set.
            - `custom_name` string, nullable: Optional user-defined name for the formula
            - `formula` string, required
          - `formulas` string[], nullable
          - `goalLines` GoalLine[], nullable: Goal Lines
            - `borderColor` string, nullable
            - `calculation` 'fixed' | 'mean' | 'median' | 'min' | 'max'
            - `displayIfCrossed` boolean, nullable
            - `displayLabel` boolean, nullable
            - `label` string, required
            - `position` 'start' | 'end'
            - `scope` 'all' | 'series'
            - `value` number, required
          - `hiddenLegendIndexes` integer[], nullable
          - `hideWeekends` boolean, nullable: Ignored. Superseded by `dateRange.daysOfWeek`, which excludes the days from the query instead of only hiding their buckets. Still accepted so existing API clients keep working.
          - `legendPosition` 'top' | 'bottom' | 'left' | 'right'
          - `metricChangeDecreaseColor` string, nullable: Metric display: change pill color when the metric decreased. Defaults to red.
          - `metricChangeIncreaseColor` string, nullable: Metric display: change pill color when the metric increased. Defaults to green.
          - `metricColorByDirection` boolean, nullable: Metric display: color the sparkline by whether the metric increased or decreased.
          - `metricLineDecreaseColor` string, nullable: Metric display: line color when the metric decreased. Defaults to red.
          - `metricLineIncreaseColor` string, nullable: Metric display: line color when the metric increased. Defaults to green.
          - `metricShowChange` boolean, nullable: Show the period-over-period change pill on the Metric display.
          - `metricSummary` 'total' | 'average' | 'latest'
          - `minDecimalPlaces` number, nullable
          - `movingAverageIntervals` number, nullable
          - `resultCustomizationBy` 'value' | 'position'
          - `resultCustomizations` union: Customizations for the appearance of result datasets.
            - object
            - object
          - `showAlertThresholdLines` boolean, nullable
          - `showAnnotations` boolean, nullable
          - `showConfidenceIntervals` boolean, nullable
          - `showLabelsOnSeries` boolean, nullable
          - `showLegend` boolean, nullable
          - `showMovingAverage` boolean, nullable
          - `showMultipleYAxes` boolean, nullable
          - `showPercentStackView` boolean, nullable
          - `showTrendLines` boolean, nullable
          - `showValuesOnSeries` boolean, nullable
          - `smoothingIntervals` integer, nullable
          - `stackBreakdownValues` boolean, nullable: On the horizontal bar-value chart, stack a series' breakdown values into a single bar instead of rendering one bar per breakdown value.
          - `xAxisLabel` string, nullable: Custom label rendered under the X axis.
          - `yAxisLabel` string, nullable: Custom label rendered alongside the Y axis.
          - `yAxisMax` number, nullable: Pins the top of the y-axis; unset means automatic. Ignored in the same cases as `yAxisStartAtZero`, and when `yAxisMin` is not below it.
          - `yAxisMin` number, nullable: Pins the bottom of the y-axis; unset means automatic. Ignored in the same cases as `yAxisStartAtZero`, while it is on, and when not below `yAxisMax`.
          - `yAxisScaleType` 'log10' | 'linear'
          - `yAxisStartAtZero` boolean, nullable: Y-axis baseline. When false the axis floats to the data range instead of starting at zero. Ignored on bar displays (bars always draw from zero), on a logarithmic scale, and while showing percentages.
        - `version` number, nullable: version of the node, used for schema migrations
      - FunnelsQuery
        - `aggregation_group_type_index` integer, nullable: Groups aggregation
        - `breakdownFilter` BreakdownFilter
          - `breakdown` union
            - string
            - union[]
              - …
            - integer
          - `breakdown_group_type_index` integer, nullable
          - `breakdown_hide_other_aggregation` boolean, nullable
          - `breakdown_histogram_bin_count` integer, nullable
          - `breakdown_limit` integer, nullable
          - `breakdown_normalize_url` boolean, nullable
          - `breakdown_path_cleaning` boolean, nullable
          - `breakdown_type` 'cohort' | 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'data_warehouse' | 'data_warehouse_person_property' | 'revenue_analytics'
          - `breakdowns` Breakdown[], nullable
            - `group_type_index` integer, nullable
            - `histogram_bin_count` integer, nullable
            - `normalize_url` boolean, nullable
            - `property` union, required
              - …
            - `type` 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'cohort' | 'revenue_analytics' | 'data_warehouse' | 'data_warehouse_person_property'
        - `compareFilter` CompareFilter
          - `compare` boolean, nullable: Whether to compare the current date range to a previous date range.
          - `compare_to` string, nullable: The date range to compare to. The value is a relative date. Examples of relative dates are: `-1y` for 1 year ago, `-14m` for 14 months ago, `-100w` for 100 weeks ago, `-14d` for 14 days ago, `-30h` for 30 hours ago.
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `funnelsFilter` FunnelsFilter
          - `annotationsScope` 'dashboard_item' | 'dashboard' | 'project' | 'organization'
          - `binCount` integer, nullable
          - `breakdownAttributionType` 'first_touch' | 'last_touch' | 'all_events' | 'step'
          - `breakdownAttributionValue` integer, nullable
          - `breakdownSorting` string, nullable: Breakdown table sorting. Format: 'column_key' or '-column_key' (descending)
          - `chartStyle` ChartStyle
            - `curve` 'linear' | 'smooth'
            - `seriesColorMode` 'palette' | 'opacity'
          - `customAggregationTarget` boolean, nullable: For data warehouse based funnel insights when the aggregation target can't be mapped to persons or groups.
          - `exclusions` union[], nullable
            - union
              - …
          - `funnelAggregateByHogQL` string, nullable
          - `funnelFromStep` integer, nullable
          - `funnelOrderType` 'strict' | 'unordered' | 'ordered'
          - `funnelStepReference` 'total' | 'previous'
          - `funnelToStep` integer, nullable: To select the range of steps for trends & time to convert funnels, 0-indexed
          - `funnelVizType` 'steps' | 'time_to_convert' | 'trends' | 'flow'
          - `funnelWindowInterval` integer, nullable
          - `funnelWindowIntervalUnit` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month'
          - `goalLines` GoalLine[], nullable: Goal Lines
            - `borderColor` string, nullable
            - `calculation` 'fixed' | 'mean' | 'median' | 'min' | 'max'
            - `displayIfCrossed` boolean, nullable
            - `displayLabel` boolean, nullable
            - `label` string, required
            - `position` 'start' | 'end'
            - `scope` 'all' | 'series'
            - `value` number, required
          - `hiddenLegendBreakdowns` string[], nullable
          - `hideIncompleteConversionWindowPeriods` boolean, nullable: Trends only: hide periods whose conversion window has not fully elapsed yet, so the recent tail of the trend isn't dragged down by entrants who still have time to convert.
          - `layout` 'horizontal' | 'vertical'
          - `legendPosition` 'top' | 'bottom' | 'left' | 'right'
          - `resultCustomizations` object, nullable: Customizations for the appearance of result datasets.
          - `showAnnotations` boolean, nullable: Whether to render annotations on the chart. Only applies to historical-trends funnels.
          - `showLegend` boolean, nullable: Whether to show a legend describing the series. The legend only renders when the funnel has multiple series. Only applies to historical-trends funnels.
          - `showTrendLines` boolean, nullable: Display linear regression trend lines on the chart (only for historical trends viz)
          - `showValuesOnSeries` boolean, nullable
          - `useUdf` boolean, nullable
        - `interval` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
        - `kind` 'FunnelsQuery'
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` FunnelsQueryResponse
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` unknown, required
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `total_median_conversion_time` number, nullable: Median total conversion time across all completers, computed breakdown-agnostically for the Steps viz header.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `samplingFactor` number, nullable: Sampling rate
        - `series` union[], required: Events and actions to include
          - union
            - EventsNode
              - …
            - ActionsNode
              - …
            - FunnelsDataWarehouseNode
              - …
            - GroupNode
              - …
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `version` number, nullable: version of the node, used for schema migrations
      - RetentionQuery
        - `aggregation_group_type_index` integer, nullable: Groups aggregation
        - `breakdownFilter` BreakdownFilter
          - `breakdown` union
            - string
            - union[]
              - …
            - integer
          - `breakdown_group_type_index` integer, nullable
          - `breakdown_hide_other_aggregation` boolean, nullable
          - `breakdown_histogram_bin_count` integer, nullable
          - `breakdown_limit` integer, nullable
          - `breakdown_normalize_url` boolean, nullable
          - `breakdown_path_cleaning` boolean, nullable
          - `breakdown_type` 'cohort' | 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'data_warehouse' | 'data_warehouse_person_property' | 'revenue_analytics'
          - `breakdowns` Breakdown[], nullable
            - `group_type_index` integer, nullable
            - `histogram_bin_count` integer, nullable
            - `normalize_url` boolean, nullable
            - `property` union, required
              - …
            - `type` 'person' | 'event' | 'event_metadata' | 'element' | 'group' | 'session' | 'hogql' | 'cohort' | 'revenue_analytics' | 'data_warehouse' | 'data_warehouse_person_property'
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `kind` 'RetentionQuery'
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` RetentionQueryResponse
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` RetentionResult[], required
            - `breakdown_value` union: Optional breakdown value for retention cohorts
              - …
            - `date` string, date-time, required
            - `label` string, required
            - `values` RetentionValue[], required
              - …
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `retentionFilter` RetentionFilter, required
          - `aggregationProperty` string, nullable: The property to aggregate when aggregationType is sum or avg
          - `aggregationPropertyType` 'event' | 'person' | 'data_warehouse'
          - `aggregationType` 'count' | 'sum' | 'avg'
          - `chartStyle` ChartStyle
            - `curve` 'linear' | 'smooth'
            - `seriesColorMode` 'palette' | 'opacity'
          - `cohortLabelStartIndex` integer, nullable: Starting index used when labeling cohort columns (e.g. 0 for D0/D1/D2, 1 for D1/D2/D3). Display-only — does not affect retention calculations.
          - `cumulative` boolean, nullable
          - `customAggregationTarget` boolean, nullable: For data warehouse based retention insights when the aggregation target can't be mapped to persons or groups.
          - `dashboardDisplay` 'table_only' | 'graph_only' | 'all'
          - `display` 'Auto' | 'ActionsLineGraph' | 'ActionsBar' | 'ActionsUnstackedBar' | 'ActionsStackedBar' | 'ActionsAreaGraph' | 'ActionsLineGraphCumulative' | 'BoldNumber' | 'Metric' | 'ActionsPie' | 'ActionsDonut' | 'ActionsProportionBar' | 'ActionsBarValue' | 'ActionsTable' | 'WorldMap' | 'CalendarHeatmap' | 'TwoDimensionalHeatmap' | 'BoxPlot' | 'SlopeGraph' | 'ScatterPlot'
          - `goalLines` GoalLine[], nullable
            - `borderColor` string, nullable
            - `calculation` 'fixed' | 'mean' | 'median' | 'min' | 'max'
            - `displayIfCrossed` boolean, nullable
            - `displayLabel` boolean, nullable
            - `label` string, required
            - `position` 'start' | 'end'
            - `scope` 'all' | 'series'
            - `value` number, required
          - `meanRetentionCalculation` 'simple' | 'weighted' | 'none'
          - `minimumOccurrences` integer, nullable
          - `period` 'Hour' | 'Day' | 'Week' | 'Month'
          - `retentionCustomBrackets` number[], nullable: Custom brackets for retention calculations
          - `retentionReference` 'total' | 'previous'
          - `retentionType` 'retention_recurring' | 'retention_first_time' | 'retention_first_ever_occurrence'
          - `returningEntity` RetentionEntity
            - `aggregation_target_field` string, nullable: Data warehouse field used as the actor identifier
            - `custom_name` string, nullable
            - `id` union
              - …
            - `kind` 'ActionsNode' | 'EventsNode'
            - `name` string, nullable
            - `order` integer, nullable
            - `properties` union[], nullable: filters on the event
              - …
            - `table_name` string, nullable: Data warehouse table name
            - `timestamp_field` string, nullable: Data warehouse timestamp field
            - `type` 'actions' | 'events' | 'data_warehouse' | 'new_entity' | 'groups'
            - `uuid` string, nullable
          - `selectedInterval` integer, nullable: The selected interval to display across all cohorts (null = show all intervals for each cohort)
          - `showMeanLine` boolean, nullable: Draw the mean across cohorts as one line on the retention graph.
          - `showTrendLines` boolean, nullable
          - `targetEntity` RetentionEntity
            - `aggregation_target_field` string, nullable: Data warehouse field used as the actor identifier
            - `custom_name` string, nullable
            - `id` union
              - …
            - `kind` 'ActionsNode' | 'EventsNode'
            - `name` string, nullable
            - `order` integer, nullable
            - `properties` union[], nullable: filters on the event
              - …
            - `table_name` string, nullable: Data warehouse table name
            - `timestamp_field` string, nullable: Data warehouse timestamp field
            - `type` 'actions' | 'events' | 'data_warehouse' | 'new_entity' | 'groups'
            - `uuid` string, nullable
          - `timeWindowMode` 'strict_calendar_dates' | '24_hour_windows'
          - `totalIntervals` integer, nullable
        - `samplingFactor` number, nullable: Sampling rate
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `version` number, nullable: version of the node, used for schema migrations
      - PathsQuery
        - `aggregation_group_type_index` integer, nullable: Groups aggregation
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `funnelPathsFilter` FunnelPathsFilter
          - `funnelPathType` 'funnel_path_before_step' | 'funnel_path_between_steps' | 'funnel_path_after_step'
          - `funnelSource` FunnelsQuery, required
            - `aggregation_group_type_index` integer, nullable: Groups aggregation
            - `breakdownFilter` BreakdownFilter
              - …
            - `compareFilter` CompareFilter
              - …
            - `dataColorTheme` number, nullable: Colors used in the insight's visualization
            - `dateRange` DateRange
              - …
            - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
            - `funnelsFilter` FunnelsFilter
              - …
            - `interval` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
            - `kind` 'FunnelsQuery'
            - `modifiers` HogQLQueryModifiers
              - …
            - `properties` union: Property filters for all series
              - …
            - `response` FunnelsQueryResponse
              - …
            - `samplingFactor` number, nullable: Sampling rate
            - `series` union[], required: Events and actions to include
              - …
            - `tags` QueryLogTags
              - …
            - `version` number, nullable: version of the node, used for schema migrations
          - `funnelStep` integer, nullable
        - `kind` 'PathsQuery'
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `pathsFilter` PathsFilter, required
          - `edgeLimit` integer, nullable
          - `endPoint` string, nullable
          - `excludeEvents` string[], nullable
          - `includeEventTypes` PathType[], nullable
          - `localPathCleaningFilters` PathCleaningFilter[], nullable
            - `alias` string, nullable: The replacement for the matched path. Use angle-bracket placeholders (`<id>`, `<uuid>`, `<slug>`) by convention, or reuse a capture group from the regex with ClickHouse `replaceRegexpAll` replacement syntax: `\1` to `\9` for a group and `\0` for the whole match.
            - `order` number, nullable
            - `regex` string, nullable
          - `maxEdgeWeight` integer, nullable
          - `minEdgeWeight` integer, nullable
          - `pathDropoffKey` string, nullable: Relevant only within actors query
          - `pathEndKey` string, nullable: Relevant only within actors query
          - `pathGroupings` string[], nullable
          - `pathReplacements` boolean, nullable
          - `pathStartKey` string, nullable: Relevant only within actors query
          - `pathsHogQLExpression` string, nullable
          - `showFullUrls` boolean, nullable
          - `startPoint` string, nullable
          - `stepLimit` integer, nullable
          - `stripQueryString` boolean, nullable: Remove the query string from page view URLs, so pages that differ only in query parameters become one path item
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` PathsQueryResponse
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` PathsLink[], required
            - `average_conversion_time` number, required
            - `source` string, required
            - `target` string, required
            - `value` number, required
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `samplingFactor` number, nullable: Sampling rate
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `version` number, nullable: version of the node, used for schema migrations
      - PathsV2Query
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `kind` 'PathsV2Query'
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `pathsV2Filter` PathsV2Filter
          - `anchor` PathsV2Anchor
            - `item` PathsV2Item, required
              - …
            - `type` 'start' | 'end', required
          - `applyTeamPathCleaning` boolean, nullable: Apply the team's path cleaning rules to naming property values before they become path items.
          - `collapseRepeats` boolean, nullable: Merge immediate repeats of the same path item within a journey.
          - `conversionWindowInterval` integer, nullable: Anchored mode's single conversion window W, anchored at the anchor and reused verbatim as the emitted funnel's window. Bounds per unit are validated server-side against CONVERSION_WINDOW_INTERVAL_BOUNDS, the same funnel conversion window bounds as the gap.
          - `conversionWindowIntervalUnit` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month'
          - `excludedItems` PathsV2Item[], nullable: Path items dropped from the item universe: events deriving to one of these items are ignored as if their event were not a step source, on both the paths side and the "view as funnel" side.
            - `event` string, required: Event of the step source this item belongs to.
            - `label` string, nullable: Label value from the source's naming property, after path cleaning. An empty string when the property is missing on the event. Null for sources without a naming property.
          - `gapInterval` integer, nullable: Inactivity gap that splits an actor's events into journeys. Bounds per unit are validated server-side against CONVERSION_WINDOW_INTERVAL_BOUNDS, the funnel conversion window bounds.
          - `gapIntervalUnit` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month'
          - `localPathCleaningFilters` PathCleaningFilter[], nullable: Path cleaning rules for this insight only, applied after the team's rules.
            - `alias` string, nullable: The replacement for the matched path. Use angle-bracket placeholders (`<id>`, `<uuid>`, `<slug>`) by convention, or reuse a capture group from the regex with ClickHouse `replaceRegexpAll` replacement syntax: `\1` to `\9` for a group and `\0` for the whole match.
            - `order` number, nullable
            - `regex` string, nullable
          - `maxRowsPerStep` integer, nullable: Number of path item rows per step; items beyond this go into the "other" row.
          - `maxSteps` integer, nullable: Number of journey steps (columns) shown.
          - `stepSources` PathsV2StepSource[], nullable: Step sources defining which events can become path items. Defaults to the pageviews preset: `$pageview` named by `$pathname`.
            - `event` string, required: Name of the event this source matches.
            - `namingProperty` string, nullable: Event property whose value labels the path item, e.g. `$pathname` for pageviews. Team path cleaning rules are applied to the value. Without a naming property, the event itself is the path item.
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` PathsV2QueryResponse
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` PathsV2Results, required
            - `edges` PathsV2Edge[], required
              - …
            - `prefixes` PathsV2Prefix[], required: Concrete anchored chains with per-chain unique-actor counts, ordered by descending count. Empty in open mode; in anchored mode it carries the counts the hover funnel preview reads per chain. Only chains the grid displays in full are carried: chains through the other bucket are omitted, so the response never exposes labels the chart hides.
              - …
            - `steps` PathsV2Step[], required
              - …
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `version` number, nullable: version of the node, used for schema migrations
      - StickinessQuery
        - `compareFilter` CompareFilter
          - `compare` boolean, nullable: Whether to compare the current date range to a previous date range.
          - `compare_to` string, nullable: The date range to compare to. The value is a relative date. Examples of relative dates are: `-1y` for 1 year ago, `-14m` for 14 months ago, `-100w` for 100 weeks ago, `-14d` for 14 days ago, `-30h` for 30 hours ago.
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `interval` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
        - `intervalCount` integer, nullable: How many intervals comprise a period. Only used for cohorts, otherwise default 1.
        - `kind` 'StickinessQuery'
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
            - `timestamp_field` string, required
          - `debug` boolean, nullable
          - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
          - `formatCsvAllowDoubleQuotes` boolean, nullable
          - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
          - `inlineCohortCalculation` 'off' | 'auto' | 'always'
          - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
          - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
          - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
          - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
          - `optimizeJoinedFilters` boolean, nullable
          - `optimizeProjections` boolean, nullable
          - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
          - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
          - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
          - `personsJoinMode` 'inner' | 'left'
          - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
          - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
          - `pushDownPredicates` boolean, nullable
          - `s3TableUseInvalidColumns` boolean, nullable
          - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
          - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
          - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
          - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
          - `sessionsV2JoinMode` 'string' | 'uuid'
          - `timings` boolean, nullable
          - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
          - `useMaterializedViews` boolean, nullable
          - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
          - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
          - `usePreaggregatedIntermediateResults` boolean, nullable
          - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
          - `useWebAnalyticsPreAggregatedTables` boolean, nullable
          - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
        - `properties` union: Property filters for all series
          - union[]
            - union
              - …
          - PropertyGroupFilter
            - `type` 'AND' | 'OR', required
            - `values` PropertyGroupFilterValue[], required
              - …
        - `response` StickinessQueryResponse
          - `error` string, nullable: Query error. Returned only if 'explain' or `modifiers.debug` is true. Throws an error otherwise.
          - `hogql` string, nullable: Generated HogQL query.
          - `modifiers` HogQLQueryModifiers
            - `bounceRateDurationSeconds` number, nullable
            - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
            - `convertToProjectTimezone` boolean, nullable
            - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
            - `customBotDefinitions` CustomBotRule[], nullable
              - …
            - `customChannelTypeRules` CustomChannelRule[], nullable
              - …
            - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
              - …
            - `debug` boolean, nullable
            - `forceClickhouseDataSkippingIndexes` string[], nullable: If these are provided, the query will fail if these skip indexes are not used
            - `formatCsvAllowDoubleQuotes` boolean, nullable
            - `inCohortVia` 'auto' | 'leftjoin' | 'subquery' | 'leftjoin_conjoined'
            - `inlineCohortCalculation` 'off' | 'auto' | 'always'
            - `materializationMode` 'auto' | 'legacy_null_as_string' | 'legacy_null_as_null' | 'disabled'
            - `materializedColumnsOptimizationMode` 'disabled' | 'optimized'
            - `mergeFederatedAggregateJoins` boolean, nullable: Merge sibling aggregating LEFT JOINs over federated Postgres tables into one UNION ALL join, so their scans overlap
            - `negatedPersonFiltersNotIn` boolean, nullable: Replace negated person-property filters in the WHERE of an `events` query (such as `email not_icontains`) with `person_id NOT IN (SELECT id FROM persons WHERE <the filters fail>)`, so the query no longer joins every person. Applies only when every filtered person property has a materialized column, nothing else in the query reads that persons join, and the join would be a LEFT JOIN.
            - `optimizeJoinedFilters` boolean, nullable
            - `optimizeProjections` boolean, nullable
            - `parserMode` 'cpp_only' | 'cpp_with_rust_shadow' | 'cpp_with_rust_py_shadow' | 'rust_with_cpp_shadow' | 'rust_only' | 'rust_py_only' | 'rust_py_with_cpp_shadow'
            - `personIdPushdown` boolean, nullable: Push an `id IN (SELECT person_id FROM <left table> WHERE …)` predicate into the joined persons subquery, so the latest-version lookup only reads persons that the outer query's left-table filters can reach. Applies only to a persons join from the query's own FROM table.
            - `personsArgMaxVersion` 'auto' | 'v1' | 'v2'
            - `personsJoinMode` 'inner' | 'left'
            - `personsOnEventsMode` 'disabled' | 'person_id_no_override_properties_on_events' | 'person_id_override_properties_on_events' | 'person_id_override_properties_joined'
            - `propertyGroupsMode` 'enabled' | 'disabled' | 'optimized'
            - `pushDownPredicates` boolean, nullable
            - `s3TableUseInvalidColumns` boolean, nullable
            - `sessionIdPushdown` boolean, nullable: Push a `session_id_v7 IN (SELECT … FROM events WHERE …)` predicate into the raw_sessions subquery to limit aggregation to sessions that participate in the outer events filter.
            - `sessionPropertyPreAggregation` boolean, nullable: Pre-filter raw_sessions aggregation by `session_id_v7 IN (cheap pre-aggregation that only materializes the columns referenced by the outer-WHERE session predicate)`. Useful when the breakdown/SELECT pulls in many session columns (e.g. `$channel_type`) but the filter only references one (e.g. `$entry_current_url`).
            - `sessionTableVersion` 'auto' | 'v1' | 'v2' | 'v3'
            - `sessionTimestampBufferMinutes` integer, nullable: Padding, in minutes, on each side of the event time range when it filters the sessions table by session start. Defaults to 3 days. It can only narrow the range: values above the default are ignored. Lower it only for a query that keeps just the sessions that start inside its own time range.
            - `sessionsV2JoinMode` 'string' | 'uuid'
            - `timings` boolean, nullable
            - `typeAwareCastSimplification` boolean, nullable: Remove provably redundant casts and nullability wrappers (e.g. `toString(String)`, `assumeNotNull(non_nullable)`, dead `ifNull` fallbacks) using inferred expression types
            - `useMaterializedViews` boolean, nullable
            - `useNewEventsCluster` boolean, nullable: Read this query from the native events cluster and native JSON events table (`true`), or keep its existing connection (`false` or unset). This is an internal rollout switch for eligible projects. PostHog staff manage eligibility through instance settings. Each query must opt in; project defaults cannot enable it. Only synchronous HogQLQuery SQL comparisons are supported.
            - `useNewEventsSchema` boolean, nullable: Read events from the native JSON events table (`true`) or the legacy events table (`false`). When unset, the project's stored value applies, then the `CLICKHOUSE_HOGQL_USE_NEW_EVENTS_SCHEMA` instance settings. This is an internal rollout switch. PostHog staff set the project value in Django admin and the project settings API ignores it.
            - `usePreaggregatedIntermediateResults` boolean, nullable
            - `usePreaggregatedTableTransforms` boolean, nullable: Try to automatically convert HogQL queries to use preaggregated tables at the AST level *
            - `useWebAnalyticsPreAggregatedTables` boolean, nullable
            - `webAnalyticsFirstPageviewFilters` boolean, nullable: Serve filters on the stored session-entry attribution properties (`$channel_type`, `$entry_utm_*`, `$entry_referring_domain`) by recomputing the value from the session's first pageview. Resolved server-side; not intended to be set by clients.
          - `query_status` QueryStatus
            - `budget_remaining_bytes` integer, nullable
            - `bytes_read` integer, nullable
            - `cache_key` string, nullable: Cache key of the run that failed, so clients can ask for its query scan.
            - `complete` boolean, nullable: Whether the query is still running. Will be true if the query is complete, even if it errored. Either result or error will be set.
            - `dashboard_id` integer, nullable
            - `end_time` string, date-time, nullable: When did the query execution task finish (whether successfully or not).
            - `error` boolean, nullable: If the query failed, this will be set to true. More information can be found in the error_message field.
            - `error_code` string, nullable: Stable machine-readable code for the error, when known: the DRF exception code, the ClickHouse error name, the HogQL error code, or `unhandled_<exception class>` for a failure that no handler classified.
            - `error_message` string, nullable
            - `expiration_time` string, date-time, nullable
            - `id` string, required
            - `insight_id` integer, nullable
            - `labels` string[], nullable
            - `pickup_time` string, date-time, nullable: When was the query execution task picked up by a worker.
            - `query_async` true: ONLY async queries use QueryStatus.
            - `query_progress` ClickhouseQueryProgress
              - …
            - `query_scan` QueryScanSummary
              - …
            - `results` unknown
            - `start_time` string, date-time, nullable: When was query execution task enqueued.
            - `task_id` string, nullable
            - `team_id` integer, required
          - `resolved_compare_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `resolved_date_range` ResolvedDateRangeResponse
            - `date_from` string, date-time, required
            - `date_to` string, date-time, required
          - `results` object[], required
          - `timings` QueryTiming[], nullable: Measured timings for different parts of the query generation process
            - `k` string, required: Key. Shortened to 'k' to save on data.
            - `t` number, required: Time in seconds. Shortened to 't' to save on data.
          - `used_data_warehouse_sources` DataWarehouseSourceUsage[], nullable: Connector-synced data warehouse sources referenced by this query, if any.
            - `id` string, required: ExternalDataSource id
            - `source_type` string, nullable: Connector type of the source (e.g. Stripe, Postgres), if known
            - `table_name` string, required: Warehouse table name that was referenced
          - `warnings` union[], nullable: Warnings about data warehouse sources referenced by the query whose latest sync failed, is paused, hit a billing limit, or is otherwise stale. Results may not reflect current source data. Accumulated across every HogQL execution that contributes to this response — so insights backed by warehouse tables (Trends, Funnels, etc.) receive the same warnings as raw HogQL queries. Also carries access control warnings when a system-table query filters out objects the user can't access.
            - union
              - …
        - `samplingFactor` number, nullable: Sampling rate
        - `series` union[], required: Events and actions to include
          - union
            - EventsNode
              - …
            - ActionsNode
              - …
            - DataWarehouseNode
              - …
        - `stickinessFilter` StickinessFilter
          - `chartStyle` ChartStyle
            - `curve` 'linear' | 'smooth'
            - `seriesColorMode` 'palette' | 'opacity'
          - `computedAs` 'non_cumulative' | 'cumulative'
          - `display` 'Auto' | 'ActionsLineGraph' | 'ActionsBar' | 'ActionsUnstackedBar' | 'ActionsStackedBar' | 'ActionsAreaGraph' | 'ActionsLineGraphCumulative' | 'BoldNumber' | 'Metric' | 'ActionsPie' | 'ActionsDonut' | 'ActionsProportionBar' | 'ActionsBarValue' | 'ActionsTable' | 'WorldMap' | 'CalendarHeatmap' | 'TwoDimensionalHeatmap' | 'BoxPlot' | 'SlopeGraph' | 'ScatterPlot'
          - `hiddenLegendIndexes` integer[], nullable
          - `legendPosition` 'top' | 'bottom' | 'left' | 'right'
          - `resultCustomizationBy` 'value' | 'position'
          - `resultCustomizations` union: Customizations for the appearance of result datasets.
            - object
            - object
          - `showLegend` boolean, nullable
          - `showMultipleYAxes` boolean, nullable
          - `showValuesOnSeries` boolean, nullable
          - `stickinessCriteria` StickinessCriteria
            - `operator` 'gte' | 'lte' | 'exact', required
            - `value` integer, required
        - `tags` QueryLogTags
          - `name` string, nullable: Name of the query, preferably unique. For example web_analytics_vitals
          - `presetId` string, nullable: Short id of the saved Web analytics filter preset this query was run under, if any.
          - `productKey` string, nullable: Product responsible for this query. Use string, there's no need to churn the Schema when we add a new product *
          - `scene` string, nullable: Scene where this query is shown in the UI. Use string, there's no need to churn the Schema when we add a new Scene *
        - `version` number, nullable: version of the node, used for schema migrations
      - LifecycleQuery
        - `aggregation_group_type_index` integer, nullable: Groups aggregation
        - `customAggregationTarget` boolean, nullable: For data warehouse based lifecycle insights when the aggregation target can't be mapped to persons or groups.
        - `dataColorTheme` number, nullable: Colors used in the insight's visualization
        - `dateRange` DateRange
          - `date_from` string, nullable: Start of the date range. Accepts ISO 8601 timestamps (e.g., 2024-01-15T00:00:00Z) or relative formats: -7d (7 days ago), -2w (2 weeks ago), -1m (1 month ago), -1h (1 hour ago), -1mStart (start of last month), -1yStart (start of last year).
          - `date_to` string, nullable: End of the date range. Same format as date_from. Omit or null for "now". A calendar day without a time (2024-01-15) is inclusive: it rounds to the last moment of that day in the project timezone, unless explicitDate is set.
          - `daysOfWeek` DaysOfWeekEnum[], nullable: Restrict the query to events occurring on these ISO days of week (1=Monday to 7=Sunday), evaluated in the project timezone. Omit or empty for all days. Only applied by insight queries.
          - `excludeIncompletePeriods` boolean, nullable: Exclude the current, still-collecting period by clipping date_to to the end of the last complete interval (evaluated in the project timezone). No-op when the range contains no complete interval. Only applied by insight queries.
          - `explicitDate` boolean, nullable: Whether the date_from and date_to should be used verbatim. Disables rounding to the start and end of period.
        - `filterTestAccounts` boolean, nullable: Exclude internal and test users by applying the respective filters
        - `interval` 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year'
        - `kind` 'LifecycleQuery'
        - `lifecycleFilter` LifecycleFilter
          - `legendPosition` 'top' | 'bottom' | 'left' | 'right'
          - `showLegend` boolean, nullable
          - `showPercentagesOnSeries` boolean, nullable: Append per-band percentage to each value label (e.g. `580 (42%)`). Requires `showValuesOnSeries` — on its own it has no visible effect.
          - `showValuesOnSeries` boolean, nullable
          - `stacked` boolean, nullable
          - `toggledLifecycles` LifecycleToggle[], nullable
        - `modifiers` HogQLQueryModifiers
          - `bounceRateDurationSeconds` number, nullable
          - `bounceRatePageViewMode` 'count_pageviews' | 'uniq_urls' | 'uniq_page_screen_autocaptures'
          - `convertToProjectTimezone` boolean, nullable
          - `cookielessTrafficIsRegular` boolean, nullable: Do not treat a missing user agent as automation on cookieless events. Positive bot signals and custom project rules still apply. Resolved server-side; not intended to be set by clients.
          - `customBotDefinitions` CustomBotRule[], nullable
            - `category` string, nullable: Reported by `$virt_traffic_category`. Defaults to `custom`.
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomBotCondition[], required
              - …
            - `name` string, required: Reported by `$virt_bot_name` and `$virt_bot_operator` when the rule matches.
          - `customChannelTypeRules` CustomChannelRule[], nullable
            - `channel_type` string, required
            - `combiner` 'AND' | 'OR', required
            - `id` string, required
            - `items` CustomChannelCondition[], required
              - …
          - `dataWarehouseEventsModifiers` DataWarehouseEventsModifier[], nullable
            - `distinct_id_field` string, required
            - `id_field` string, required
            - `table_name` string, required
- … truncated; see the full OpenAPI document linked below

## Response `200`

- PropertiesTimelineResponse
  - `points` PropertiesTimelinePoint[], required: One point for each change of the key property values, oldest first.
    - `timestamp` string, date-time, required: The time of the first event in the window that has this combination of key property values.
    - `properties` object, required: The person's properties as that event recorded them.
    - `relevant_event_count` integer, required: The number of the person's events in the window from this point until the next point.
  - `crucial_property_keys` string[], required: The key person properties: those the insight's query uses. Empty when it uses none.
  - `effective_date_from` string, date-time, required: The start of the window, in the project's time zone.
  - `effective_date_to` string, date-time, required: The end of the window, in the project's time zone.

## Changes

> 53 revisions in range; 1 not diffed.

- **2026-10-22** `bab3bb4f0c72`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/posthog/apis/posthog-api/changes/api/projects/:project_id/persons/:id/properties_timeline/post.md)

---

[API](https://skmtc.dev/posthog/apis/posthog-api.md) · [All operations](https://skmtc.dev/posthog/apis/posthog-api/llms.txt) · [OpenAPI document](https://skmtc.dev/posthog/apis/posthog-api/revisions/993f70ab941b?raw)
