Agent Skills: PostHog API

PostHog API for product analytics. Use when user mentions "PostHog",

UncategorizedID: vm0-ai/vm0-skills/posthog

Install this agent skill to your local

pnpm dlx add-skill https://github.com/vm0-ai/vm0-skills/tree/HEAD/posthog

Skill Files

Browse the full folder contents for posthog.

Download Skill

Loading file tree…

posthog/SKILL.md

Skill Metadata

Name
posthog
Description
PostHog API for product analytics. Use when user mentions "PostHog",

PostHog API

Use the PostHog API via direct curl calls to manage product analytics, feature flags, experiments, insights, dashboards, cohorts, annotations, and surveys.

Official docs: https://posthog.com/docs/api


When to Use

Use this skill when you need to:

  • Manage feature flags - create, update, list, and toggle feature flags
  • Run experiments - create and monitor A/B tests
  • Query analytics - run HogQL queries for custom analytics
  • Manage insights - create and retrieve saved insights (trends, funnels, retention)
  • Manage dashboards - create and organize dashboards
  • Track persons and events - query user data and event streams
  • Manage cohorts - create and query user segments
  • Create annotations - add timeline markers for deployments or incidents
  • Manage surveys - create and monitor in-app surveys

Prerequisites

Discovering Your Project ID

Most endpoints require a project ID. Get it from the projects endpoint:

curl -s "https://us.posthog.com/api/projects/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name}'

Verify Authentication

curl -s "https://us.posthog.com/api/users/@me/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{uuid, first_name, email}'

How to Use

All examples below assume POSTHOG_TOKEN is set. Replace <project-id> with your actual project ID from the prerequisites step.

Base URL: https://us.posthog.com/api


Organizations

List Organizations

curl -s "https://us.posthog.com/api/organizations/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, slug, created_at}'

Get Organization Details

Replace <org-id> with your organization ID:

curl -s "https://us.posthog.com/api/organizations/<org-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, name, slug, created_at, membership_level}'

Projects

List Projects

curl -s "https://us.posthog.com/api/projects/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, timezone}'

Get Project Details

Replace <project-id> with your project ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, name, timezone, completed_snippet_onboarding, ingested_event}'

Feature Flags

List Feature Flags

curl -s "https://us.posthog.com/api/projects/<project-id>/feature_flags/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, key, name, active}'

Get Feature Flag Details

Replace <flag-id> with the feature flag ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/feature_flags/<flag-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, key, name, active, filters, rollout_percentage}'

Create Feature Flag

Write to /tmp/posthog_request.json:

{
  "key": "my-new-flag",
  "name": "My New Feature Flag",
  "active": true,
  "filters": {
    "groups": [
      {
        "properties": [],
        "rollout_percentage": 100
      }
    ]
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/feature_flags/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, key, name, active}'

Update Feature Flag

Write to /tmp/posthog_request.json:

{
  "active": false
}

Replace <flag-id> with the feature flag ID:

curl -s -X PATCH "https://us.posthog.com/api/projects/<project-id>/feature_flags/<flag-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, key, name, active}'

Delete Feature Flag

Replace <flag-id> with the feature flag ID:

curl -s -X DELETE "https://us.posthog.com/api/projects/<project-id>/feature_flags/<flag-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)"

Experiments

List Experiments

curl -s "https://us.posthog.com/api/projects/<project-id>/experiments/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, start_date, end_date, feature_flag_key}'

Get Experiment Details

Replace <experiment-id> with the experiment ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/experiments/<experiment-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, name, description, start_date, end_date, feature_flag_key, parameters}'

Create Experiment

Write to /tmp/posthog_request.json:

{
  "name": "Button Color Test",
  "description": "Testing red vs blue button",
  "feature_flag_key": "button-color-test",
  "parameters": {
    "feature_flag_variants": [
      {"key": "control", "rollout_percentage": 50},
      {"key": "test", "rollout_percentage": 50}
    ]
  },
  "filters": {
    "events": [{"id": "$pageview", "name": "$pageview"}]
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/experiments/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name, feature_flag_key}'

Insights

List Saved Insights

curl -s "https://us.posthog.com/api/projects/<project-id>/insights/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, short_id, name, filters}'

Get Insight Details

Replace <insight-id> with the insight ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/insights/<insight-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, short_id, name, description, filters, last_refresh}'

Create Trend Insight

Write to /tmp/posthog_request.json:

{
  "name": "Daily Pageviews",
  "filters": {
    "insight": "TRENDS",
    "events": [{"id": "$pageview", "name": "$pageview", "math": "total"}],
    "date_from": "-30d"
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/insights/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, short_id, name}'

Create Funnel Insight

Write to /tmp/posthog_request.json:

{
  "name": "Signup Funnel",
  "filters": {
    "insight": "FUNNELS",
    "events": [
      {"id": "$pageview", "order": 0},
      {"id": "signup_started", "order": 1},
      {"id": "signup_completed", "order": 2}
    ],
    "date_from": "-30d"
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/insights/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, short_id, name}'

Delete Insight

Replace <insight-id> with the insight ID:

curl -s -X DELETE "https://us.posthog.com/api/projects/<project-id>/insights/<insight-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)"

Dashboards

List Dashboards

curl -s "https://us.posthog.com/api/projects/<project-id>/dashboards/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, description, created_at}'

Get Dashboard Details

Replace <dashboard-id> with the dashboard ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/dashboards/<dashboard-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, name, description, tiles: [.tiles[] | {id, insight: .insight.name}]}'

Create Dashboard

Write to /tmp/posthog_request.json:

{
  "name": "Engineering Dashboard",
  "description": "Key engineering metrics"
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/dashboards/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'

Delete Dashboard

Replace <dashboard-id> with the dashboard ID:

curl -s -X DELETE "https://us.posthog.com/api/projects/<project-id>/dashboards/<dashboard-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)"

HogQL Queries

Run arbitrary analytics queries using HogQL (PostHog's SQL dialect).

Run a HogQL Query

Write to /tmp/posthog_request.json:

{
  "query": {
    "kind": "HogQLQuery",
    "query": "SELECT event, count() as cnt FROM events GROUP BY event ORDER BY cnt DESC LIMIT 10"
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{columns, results}'

Count Events by Day

Write to /tmp/posthog_request.json:

{
  "query": {
    "kind": "HogQLQuery",
    "query": "SELECT toDate(timestamp) as day, count() as cnt FROM events WHERE timestamp > now() - INTERVAL 7 DAY GROUP BY day ORDER BY day DESC"
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{columns, results}'

Query Persons

Write to /tmp/posthog_request.json:

{
  "query": {
    "kind": "HogQLQuery",
    "query": "SELECT distinct_id, properties.$browser as browser, properties.$os as os FROM persons LIMIT 10"
  }
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{columns, results}'

Events

List Recent Events

curl -s "https://us.posthog.com/api/projects/<project-id>/events/?limit=10" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, event, distinct_id, timestamp}'

Filter Events by Type

Replace $pageview with the event name you want to filter:

curl -s "https://us.posthog.com/api/projects/<project-id>/events/?event=%24pageview&limit=10" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, event, distinct_id, timestamp, properties}'

Persons

List Persons

curl -s "https://us.posthog.com/api/projects/<project-id>/persons/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, distinct_ids, properties}'

Search Persons

curl -s "https://us.posthog.com/api/projects/<project-id>/persons/?search=user@example.com" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, distinct_ids}'

Get Person Details

Replace <person-id> with the person ID:

curl -s "https://us.posthog.com/api/projects/<project-id>/persons/<person-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '{id, distinct_ids, properties, created_at}'

Cohorts

List Cohorts

curl -s "https://us.posthog.com/api/projects/<project-id>/cohorts/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, count, created_at}'

Create Cohort

Write to /tmp/posthog_request.json:

{
  "name": "Power Users",
  "groups": [
    {
      "properties": [
        {
          "key": "$pageview",
          "type": "behavioral",
          "value": "performed_event",
          "event_type": "events",
          "time_value": 7,
          "time_interval": "day",
          "total_periods": 3
        }
      ]
    }
  ]
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/cohorts/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'

Annotations

List Annotations

curl -s "https://us.posthog.com/api/projects/<project-id>/annotations/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, content, date_marker, scope}'

Create Annotation

Write to /tmp/posthog_request.json:

{
  "content": "Deployed v2.1.0",
  "date_marker": "2026-03-10T00:00:00Z",
  "scope": "organization"
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/annotations/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, content, date_marker}'

Delete Annotation

Replace <annotation-id> with the annotation ID:

curl -s -X DELETE "https://us.posthog.com/api/projects/<project-id>/annotations/<annotation-id>/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)"

Actions

List Actions

curl -s "https://us.posthog.com/api/projects/<project-id>/actions/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, steps}'

Create Action

Write to /tmp/posthog_request.json:

{
  "name": "Clicked Sign Up",
  "steps": [
    {
      "event": "$autocapture",
      "properties": [
        {"key": "$element_text", "value": "Sign Up", "type": "element"}
      ]
    }
  ]
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/actions/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'

Surveys

List Surveys

curl -s "https://us.posthog.com/api/projects/<project-id>/surveys/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {id, name, type, start_date, end_date}'

Create Survey

Write to /tmp/posthog_request.json:

{
  "name": "NPS Survey",
  "type": "popover",
  "questions": [
    {
      "type": "rating",
      "question": "How likely are you to recommend us?",
      "display": "number",
      "scale": 10,
      "lowerBoundLabel": "Not likely",
      "upperBoundLabel": "Very likely"
    }
  ]
}
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/surveys/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name, type}'

Event Definitions

List Event Definitions

Discover what events are tracked in your project:

curl -s "https://us.posthog.com/api/projects/<project-id>/event_definitions/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {name, volume_30_day, query_usage_30_day}'

Property Definitions

List Property Definitions

Discover what properties are available:

curl -s "https://us.posthog.com/api/projects/<project-id>/property_definitions/" --header "Authorization: Bearer $(printenv POSTHOG_TOKEN)" | jq '.results[] | {name, property_type, is_numerical}'

Guidelines

  1. Discover project ID first: Call the projects endpoint to get your project ID before using other endpoints
  2. Pagination: Responses use count, next, and previous fields. Use ?limit=N&offset=M for pagination
  3. HogQL for complex queries: Use the query endpoint with HogQL for custom analytics that go beyond the standard endpoints
  4. Rate limits: PostHog has rate limits; implement backoff for 429 responses
  5. US vs EU: Use us.posthog.com for US Cloud or eu.posthog.com for EU Cloud
  6. Event names: PostHog built-in events start with $ (e.g., $pageview, $autocapture). URL-encode the $ as %24 in query parameters