Skip to main content

Query Insights

Execute insight queries and retrieve results without creating a saved insight. This endpoint is useful for exploratory analysis, building custom dashboards, or programmatically analyzing your PostHog data.

Endpoint

POST /api/projects/:project_id/query/

Path Parameters

project_id
integer
required
The ID of the project to query

Query Parameters

refresh
string
How to handle result calculation:
  • force_cache - Return cached data only (fastest, may return cache miss)
  • blocking - Calculate synchronously if cache is stale
  • async - Kick off background calculation if needed, return immediately
  • lazy_async - Background calculation for somewhat stale cache
  • force_blocking - Always calculate synchronously
  • force_async - Always calculate in background
Default: force_cache
client_query_id
string
Optional client-provided query ID for tracking and cancellation

Request Body

The request body should contain a query object matching one of the supported query types.
kind
string
required
Set to TrendsQuery for trends analysis
series
array
required
Array of event or action nodes to analyze
dateRange
object
Date range for the analysis (e.g., {"date_from": "-7d"})
interval
string
Time interval: hour, day, week, month
breakdownFilter
object
Break down results by properties
properties
array
Filter events by properties

Funnels Query

kind
string
required
Set to FunnelsQuery for conversion funnel analysis
series
array
required
Ordered array of funnel steps (events or actions)
funnelWindowInterval
number
Time window for conversion (e.g., 7)
funnelWindowIntervalUnit
string
Unit for funnel window: hour, day, week, month

HogQL Query

kind
string
required
Set to HogQLQuery for SQL queries
query
string
required
HogQL (SQL-like) query string

Response Fields

results
any
Query results (format depends on query type)
hasMore
boolean
Whether there are more results available (for paginated queries)
columns
array
Column definitions (for table results)
types
array
Data types for each column
hogql
string
The HogQL query that was executed (for debugging)
query_status
object
Query execution status and metadata
id
string
Query ID
complete
boolean
Whether query execution is complete
error
boolean
Whether an error occurred
error_message
string
Error message if query failed
last_refresh
string
ISO 8601 timestamp of when results were calculated
is_cached
boolean
Whether results came from cache
timezone
string
Timezone used for date calculations
timings
array
Performance timing information

Examples

Query pageview trends over the last 7 days:
curl -X POST https://app.posthog.com/api/projects/12345/query/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "TrendsQuery",
    "series": [
      {
        "kind": "EventsNode",
        "event": "$pageview",
        "name": "$pageview"
      }
    ],
    "dateRange": {
      "date_from": "-7d"
    },
    "interval": "day"
  }'

Funnel Query

Analyze conversion through a signup funnel:
curl -X POST "https://app.posthog.com/api/projects/12345/query/?refresh=blocking" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "FunnelsQuery",
    "series": [
      {
        "kind": "EventsNode",
        "event": "signup_started",
        "name": "Started Signup"
      },
      {
        "kind": "EventsNode",
        "event": "signup_completed",
        "name": "Completed Signup"
      }
    ],
    "dateRange": {
      "date_from": "-30d"
    },
    "funnelWindowInterval": 1,
    "funnelWindowIntervalUnit": "day"
  }'

HogQL Query

Run a SQL query using HogQL:
curl -X POST https://app.posthog.com/api/projects/12345/query/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "HogQLQuery",
    "query": "SELECT event, count() as count FROM events WHERE timestamp > now() - INTERVAL 7 DAY GROUP BY event ORDER BY count DESC LIMIT 10"
  }'

Query with Breakdown

Analyze events broken down by a property:
curl -X POST https://app.posthog.com/api/projects/12345/query/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "TrendsQuery",
    "series": [
      {
        "kind": "EventsNode",
        "event": "purchase_completed"
      }
    ],
    "dateRange": {
      "date_from": "-30d"
    },
    "breakdownFilter": {
      "breakdown_type": "event",
      "breakdown": "product_category"
    },
    "interval": "day"
  }'

Response Examples

{
  "results": [
    {
      "action": {
        "id": "$pageview",
        "type": "events",
        "order": 0,
        "name": "$pageview",
        "custom_name": null
      },
      "label": "$pageview",
      "count": 15234,
      "data": [1820, 2103, 2456, 2187, 2034, 2289, 2345],
      "labels": ["15-Jan-2024", "16-Jan-2024", "17-Jan-2024", "18-Jan-2024", "19-Jan-2024", "20-Jan-2024", "21-Jan-2024"],
      "days": ["2024-01-15", "2024-01-16", "2024-01-17", "2024-01-18", "2024-01-19", "2024-01-20", "2024-01-21"]
    }
  ],
  "hasMore": false,
  "last_refresh": "2024-01-21T15:30:00Z",
  "is_cached": true,
  "timezone": "UTC",
  "query_status": {
    "complete": true,
    "error": false
  },
  "timings": [
    {
      "k": "query_execution",
      "t": 0.123
    }
  ]
}

Funnel Query Response

{
  "results": [
    {
      "name": "Started Signup",
      "count": 5420,
      "order": 0,
      "conversion_rate": 100.0
    },
    {
      "name": "Completed Signup",
      "count": 3254,
      "order": 1,
      "conversion_rate": 60.04,
      "average_conversion_time": 324.5
    }
  ],
  "is_cached": false,
  "last_refresh": "2024-01-21T15:30:00Z",
  "timezone": "UTC",
  "query_status": {
    "complete": true,
    "error": false
  }
}

HogQL Query Response

{
  "results": [
    ["$pageview", 15234],
    ["signup_completed", 3254],
    ["purchase_completed", 1847],
    ["add_to_cart", 4521],
    ["user_login", 8932]
  ],
  "columns": ["event", "count"],
  "types": ["String", "UInt64"],
  "hogql": "SELECT event, count() as count FROM events WHERE timestamp > now() - INTERVAL 7 DAY GROUP BY event ORDER BY count DESC LIMIT 10",
  "hasMore": false,
  "is_cached": false,
  "last_refresh": "2024-01-21T15:30:00Z"
}

Error Responses

400 Bad Request
error
Invalid query structure
{
  "detail": "Query must be a valid JSON object"
}
401 Unauthorized
error
Invalid or missing API key
403 Forbidden
error
Insufficient permissions to query data
429 Too Many Requests
error
Rate limit exceeded
{
  "detail": "Request was throttled. Expected available in 42 seconds."
}
500 Internal Server Error
error
Query execution error
{
  "query_status": {
    "error": true,
    "error_message": "Query timeout after 60 seconds"
  }
}

Notes

  • Queries are executed against your ClickHouse analytics database
  • Results are cached for performance; use refresh parameter to control caching behavior
  • Use force_cache for fastest responses (may return cache miss if no cached results)
  • Use blocking to ensure fresh results while maintaining synchronous response
  • Use async for expensive queries to avoid timeouts
  • Query execution is subject to rate limits
  • HogQL queries must be read-only (SELECT statements only)
  • Results are automatically formatted based on query type
  • Aggregate queries (count, sum, etc.) return numeric results
  • Time-series queries return arrays of data points

Build docs developers (and LLMs) love