posthog
$
npx mdskill add vm0-ai/vm0-skills/posthogExecute 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
- 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".