posthog

$npx mdskill add vm0-ai/vm0-skills/posthog

Execute PostHog API calls to manage analytics and feature flags.

  • Retrieves organizations, projects, and feature flag data.
  • Requires valid POSTHOG_TOKEN and project ID credentials.
  • Selects endpoints based on requested analytics or flag operations.
  • Returns structured JSON responses via curl commands.

SKILL.md

.github/skills/posthogView on GitHub ↗
---
name: posthog
description: PostHog API for product analytics. Use when user mentions "PostHog",
  "product analytics", "event tracking", or user analytics.
---

## Troubleshooting

If requests fail, run `zero doctor check-connector --env-name POSTHOG_TOKEN` or `zero doctor check-connector --url https://us.posthog.com/api/organizations/ --method GET`

## 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

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

### Get Organization Details

Replace `<org-id>` with your organization ID:

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

## Projects

### List Projects

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

### Get Project Details

Replace `<project-id>` with your project ID:

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

## Feature Flags

### List Feature Flags

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

### Get Feature Flag Details

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

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

### Create Feature Flag

Write to `/tmp/posthog_request.json`:

```json
{
  "key": "my-new-flag",
  "name": "My New Feature Flag",
  "active": true,
  "filters": {
    "groups": [
      {
        "properties": [],
        "rollout_percentage": 100
      }
    ]
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/feature_flags/" --header "Authorization: Bearer $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`:

```json
{
  "active": false
}
```

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

```bash
curl -s -X PATCH "https://us.posthog.com/api/projects/<project-id>/feature_flags/<flag-id>/" --header "Authorization: Bearer $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:

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

## Experiments

### List Experiments

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

### Get Experiment Details

Replace `<experiment-id>` with the experiment ID:

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

### Create Experiment

Write to `/tmp/posthog_request.json`:

```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"}]
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/experiments/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name, feature_flag_key}'
```

## Insights

### List Saved Insights

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

### Get Insight Details

Replace `<insight-id>` with the insight ID:

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

### Create Trend Insight

Write to `/tmp/posthog_request.json`:

```json
{
  "name": "Daily Pageviews",
  "filters": {
    "insight": "TRENDS",
    "events": [{"id": "$pageview", "name": "$pageview", "math": "total"}],
    "date_from": "-30d"
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/insights/" --header "Authorization: Bearer $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`:

```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"
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/insights/" --header "Authorization: Bearer $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:

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

## Dashboards

### List Dashboards

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

### Get Dashboard Details

Replace `<dashboard-id>` with the dashboard ID:

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

### Create Dashboard

Write to `/tmp/posthog_request.json`:

```json
{
  "name": "Engineering Dashboard",
  "description": "Key engineering metrics"
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/dashboards/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'
```

### Delete Dashboard

Replace `<dashboard-id>` with the dashboard ID:

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

## HogQL Queries

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

### Run a HogQL Query

Write to `/tmp/posthog_request.json`:

```json
{
  "query": {
    "kind": "HogQLQuery",
    "query": "SELECT event, count() as cnt FROM events GROUP BY event ORDER BY cnt DESC LIMIT 10"
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $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`:

```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"
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{columns, results}'
```

### Query Persons

Write to `/tmp/posthog_request.json`:

```json
{
  "query": {
    "kind": "HogQLQuery",
    "query": "SELECT distinct_id, properties.$browser as browser, properties.$os as os FROM persons LIMIT 10"
  }
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/query/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{columns, results}'
```

## Events

### List Recent Events

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

### Filter Events by Type

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

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

## Persons

### List Persons

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

### Search Persons

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

### Get Person Details

Replace `<person-id>` with the person ID:

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

## Cohorts

### List Cohorts

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

### Create Cohort

Write to `/tmp/posthog_request.json`:

```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
        }
      ]
    }
  ]
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/cohorts/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'
```

## Annotations

### List Annotations

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

### Create Annotation

Write to `/tmp/posthog_request.json`:

```json
{
  "content": "Deployed v2.1.0",
  "date_marker": "2026-03-10T00:00:00Z",
  "scope": "organization"
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/annotations/" --header "Authorization: Bearer $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:

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

## Actions

### List Actions

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

### Create Action

Write to `/tmp/posthog_request.json`:

```json
{
  "name": "Clicked Sign Up",
  "steps": [
    {
      "event": "$autocapture",
      "properties": [
        {"key": "$element_text", "value": "Sign Up", "type": "element"}
      ]
    }
  ]
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/actions/" --header "Authorization: Bearer $POSTHOG_TOKEN" --header "Content-Type: application/json" -d @/tmp/posthog_request.json | jq '{id, name}'
```

## Surveys

### List Surveys

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

### Create Survey

Write to `/tmp/posthog_request.json`:

```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"
    }
  ]
}
```

```bash
curl -s -X POST "https://us.posthog.com/api/projects/<project-id>/surveys/" --header "Authorization: Bearer $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:

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

## Property Definitions

### List Property Definitions

Discover what properties are available:

```bash
curl -s "https://us.posthog.com/api/projects/<project-id>/property_definitions/" --header "Authorization: Bearer $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

More from vm0-ai/vm0-skills

SkillDescription
account-reconciliationPerform account reconciliations comparing general ledger balances against subledgers, bank statements, or external records. Use for bank reconciliation, GL-to-subledger reconciliation, intercompany reconciliation, balance sheet reconciliation, reconciling item analysis, outstanding item aging, or clearing open items.
agentphoneBuild AI phone agents with AgentPhone API. Use when the user wants to make phone calls, send/receive SMS, manage phone numbers, create voice agents, set up webhooks, or check usage — anything related to telephony, phone numbers, or voice AI.
ahrefsAhrefs SEO API for backlink and keyword analysis. Use when user mentions
amplitudeAmplitude product analytics API. Use when user mentions "Amplitude",
analysis-qaQuality-check a data analysis before sharing — verify joins, aggregations, denominators, time ranges, and metric definitions. Detect pitfalls like survivorship bias, average-of-averages, join explosion, timezone mismatches, incomplete periods, and selection bias. Includes documentation templates for reproducible analyses.
anthropic-managed-agentsAnthropic Managed Agents API for programmatically creating, running, and streaming AI agents on Anthropic's cloud infrastructure. Use when the user mentions "Managed Agents", "Anthropic agent sessions", or needs to create/run/stream an Anthropic agent with tool use (bash, git, web), attach GitHub repositories, or inject secrets via Vault. Do NOT use for standard Claude Messages API — use the Claude API skill instead.
apifyApify web scraping platform. Use when user mentions "scrape website",
asanaAsana API for tasks and projects. Use when user mentions "Asana", "asana.com",
atlassianAtlassian API for Confluence and Jira. Use when user mentions "Confluence
attioAttio REST API for AI-native CRM operations — manage companies, people, deals, and custom objects, plus notes, tasks, lists, and comments. Use when the user mentions "Attio", "CRM record", "create company", "add person", "list entry", "CRM note", or "CRM task".