A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The PostHog API is how an app or AI agent works with a PostHog project: sending events in, running HogQL queries to read them back, reading and updating the people behind the analytics, and managing feature flags, insights, and experiments. Access splits in two: a project key sends events in and carries no permissions, while a personal API key reads and manages data and carries fine-grained scopes, each set to read or write per resource and limited to chosen organizations and projects. There is no dated version to pin, since one continuously updated API is announced through a changelog.
How an app or AI agent connects to PostHog determines what it can reach. There is a route for sending events, a route for reading and managing data, and a hosted server that exposes PostHog tools to agents, and each is governed by the key behind it and the scopes that key carries.
The private REST API answers at us.posthog.com on US Cloud and eu.posthog.com on EU Cloud, and handles all reading and management. It authenticates with a personal API key and is scoped by that key's permissions.
The public capture API answers at us.i.posthog.com on US Cloud and eu.i.posthog.com on EU Cloud, and takes events into PostHog. It authenticates with the project token in the request body, carries no scopes, and is not rate limited.
PostHog runs a hosted MCP server at mcp.posthog.com/mcp that lets an agent work with PostHog through the Model Context Protocol, including reading insights, running HogQL queries, managing feature flags, and inspecting errors. The login routes to the right region, US or EU, and the source lives in the PostHog monorepo at github.com/PostHog/posthog under services/mcp.
A personal API key, prefixed phx_, is sent as 'Authorization: Bearer
A project API key authenticates the public capture and flag-evaluation endpoints by being sent in the request body. It is tied to one project, carries no scopes, and is safe to expose in client code because it cannot read data back.
OAuth lets an app that other PostHog users install request scoped access to their account, so they grant permission without sharing a personal API key.
The PostHog API is split into areas an agent can act on, like events, queries, persons, insights, and feature flags. Each area has its own methods and its own scope, and reading persons returns the people and properties behind the analytics.
Send a single event or a batch of events into PostHog for ingestion.
Run a HogQL query, PostHog's SQL dialect, to read events, persons, and aggregates.
List, read, update, and delete the people PostHog has tracked and their properties.
List, read, and create saved insights, the charts and tables built from events.
List, read, create, and update feature flags, and evaluate flags for a person.
List, read, and create cohorts, the saved groups of people that match a rule.
List, read, and create dashboards, the collections of insights shown together.
List and create annotations, the dated notes that mark events on a chart.
List and create experiments, the A/B tests built on top of feature flags.
List and create actions, the saved combinations of events used across PostHog.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
Event captureSend a single event or a batch of events into PostHog for ingestion.2 | ||||||
| POST | /i/v0/e/ | Capture a single event for a person. | write | — | Current | |
A public POST-only endpoint that authenticates with the project API key sent in the request body, not a personal API key. It carries no scopes and is not rate limited. Acts onevent Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitNot rate limited SourceOfficial documentation ↗ | ||||||
| POST | /batch/ | Capture a batch of events in one request. | write | — | Current | |
A public POST-only endpoint that authenticates with the project API key in the request body. It carries no scopes and is not rate limited. Acts onevent Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitNot rate limited SourceOfficial documentation ↗ | ||||||
Query (HogQL)Run a HogQL query, PostHog's SQL dialect, to read events, persons, and aggregates.1 | ||||||
| POST | /api/projects/:project_id/query/ | Run a query, including a HogQL SQL query, over a project's data. | read | query:read | Current | |
The main endpoint for reading data from PostHog. A HogQL query can reach events, persons, and aggregates across the project, so this single scope grants broad read access. Acts onquery Permission (capability) query:readVersionAvailable since the API’s base version Webhook eventNone Rate limit2,400/hour SourceOfficial documentation ↗ | ||||||
PersonsList, read, update, and delete the people PostHog has tracked and their properties.4 | ||||||
| GET | /api/environments/:environment_id/persons/ | List the persons tracked in a project. | read | person:read | Current | |
Returns person records and their properties, which can include names, emails, and other identifying fields that were captured. Acts onperson Permission (capability) person:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| GET | /api/environments/:environment_id/persons/:id/ | Get a single person by id. | read | person:read | Current | |
Returns one person's full property set. Acts onperson Permission (capability) person:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| PATCH | /api/environments/:environment_id/persons/:id/ | Update a person's properties. | write | person:write | Current | |
PostHog recommends setting person properties through capture and the SDKs rather than this endpoint, which is meant mainly for reading and deleting. Acts onperson Permission (capability) person:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/environments/:environment_id/persons/bulk_delete/ | Delete persons in bulk, optionally removing their events too. | write | person:write | Current | |
Deletes person records and can also delete the events tied to them, which removes data permanently. Acts onperson Permission (capability) person:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
InsightsList, read, and create saved insights, the charts and tables built from events.3 | ||||||
| GET | /api/environments/:environment_id/insights/ | List saved insights in a project. | read | insight:read | Current | |
Reading an insight returns its definition and computed results. Acts oninsight Permission (capability) insight:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| GET | /api/environments/:environment_id/insights/:id/ | Get a single saved insight by id. | read | insight:read | Current | |
Computing the insight result can be the slow part of this call. Acts oninsight Permission (capability) insight:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/environments/:environment_id/insights/ | Create a saved insight. | write | insight:write | Current | |
Creates a new saved chart or table that others on the team will see. Acts oninsight Permission (capability) insight:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
Feature flagsList, read, create, and update feature flags, and evaluate flags for a person.5 | ||||||
| GET | /api/projects/:project_id/feature_flags/ | List the feature flags in a project. | read | feature_flag:read | Current | |
Returns each flag's key, rollout, and targeting rules. Acts onfeature flag Permission (capability) feature_flag:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| GET | /api/projects/:project_id/feature_flags/:id/ | Get a single feature flag by id. | read | feature_flag:read | Current | |
Returns one flag's full definition. Acts onfeature flag Permission (capability) feature_flag:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/projects/:project_id/feature_flags/ | Create a feature flag. | write | feature_flag:write | Current | |
A new flag can immediately change which users see a feature, depending on its rollout. Acts onfeature flag Permission (capability) feature_flag:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
| PATCH | /api/projects/:project_id/feature_flags/:id/ | Update a feature flag, such as its rollout or targeting. | write | feature_flag:write | Current | |
Changing a rollout percentage here takes effect in production for matching users. Acts onfeature flag Permission (capability) feature_flag:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
| POST | /flags | Evaluate the feature flags, experiments, and surveys that apply to a person. | read | — | Current | |
A public POST-only endpoint that uses the project token, not a personal API key. It returns the flag values for a given distinct_id and is the endpoint SDKs call to decide what a user sees. Acts onfeature flag Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitNot rate limited SourceOfficial documentation ↗ | ||||||
CohortsList, read, and create cohorts, the saved groups of people that match a rule.3 | ||||||
| GET | /api/projects/:project_id/cohorts/ | List the cohorts in a project. | read | cohort:read | Current | |
Returns each cohort's definition and the rule that selects its people. Acts oncohort Permission (capability) cohort:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| GET | /api/projects/:project_id/cohorts/:id/ | Get a single cohort by id. | read | cohort:read | Current | |
Returns one cohort's full definition. Acts oncohort Permission (capability) cohort:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/projects/:project_id/cohorts/ | Create a cohort. | write | cohort:write | Current | |
Creates a saved group of people that other features, such as feature flags, can target. Acts oncohort Permission (capability) cohort:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
DashboardsList, read, and create dashboards, the collections of insights shown together.3 | ||||||
| GET | /api/environments/:environment_id/dashboards/ | List the dashboards in a project. | read | dashboard:read | Current | |
Returns each dashboard and the insights it holds. Acts ondashboard Permission (capability) dashboard:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| GET | /api/environments/:environment_id/dashboards/:id/ | Get a single dashboard by id. | read | dashboard:read | Current | |
Returns one dashboard and its tiles. Acts ondashboard Permission (capability) dashboard:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/environments/:environment_id/dashboards/ | Create a dashboard. | write | dashboard:write | Current | |
Creates a new dashboard that the team will see. Acts ondashboard Permission (capability) dashboard:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
AnnotationsList and create annotations, the dated notes that mark events on a chart.2 | ||||||
| GET | /api/projects/:project_id/annotations/ | List the annotations in a project. | read | annotation:read | Current | |
Returns the dated notes that mark events on charts. Acts onannotation Permission (capability) annotation:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/projects/:project_id/annotations/ | Create an annotation. | write | annotation:write | Current | |
Adds a dated note that appears on charts across the project. Acts onannotation Permission (capability) annotation:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
ExperimentsList and create experiments, the A/B tests built on top of feature flags.2 | ||||||
| GET | /api/projects/:project_id/experiments/ | List the experiments in a project. | read | experiment:read | Current | |
Returns each A/B test and the feature flag behind it. Acts onexperiment Permission (capability) experiment:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/projects/:project_id/experiments/ | Create an experiment. | write | experiment:write | Current | |
Creating an experiment also creates the feature flag that splits its variants. Acts onexperiment Permission (capability) experiment:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
ActionsList and create actions, the saved combinations of events used across PostHog.2 | ||||||
| GET | /api/projects/:project_id/actions/ | List the actions in a project. | read | action:read | Current | |
Returns each saved combination of events that PostHog tracks as one action. Acts onaction Permission (capability) action:readVersionAvailable since the API’s base version Webhook eventNone Rate limit240/minute and 1,200/hour SourceOfficial documentation ↗ | ||||||
| POST | /api/projects/:project_id/actions/ | Create an action. | write | action:write | Current | |
Creates a saved action that insights and other features can reference. Acts onaction Permission (capability) action:writeVersionAvailable since the API’s base version Webhook eventNone Rate limit480/minute and 4,800/hour SourceOfficial documentation ↗ | ||||||
PostHog can notify an app or AI agent when something happens, instead of the app repeatedly asking. A realtime destination or an action posts the matching event to a receiver URL that has been set up for it.
| Event | What it signals | Triggered by |
|---|
PostHog limits how fast an app or AI agent can call the private read and management endpoints, through per-minute and per-hour ceilings that vary by endpoint type, while the public event-capture endpoints are not rate limited.
PostHog rate limits its private read and management endpoints, and the limit applies across the whole organization rather than per key. The analytics endpoints, such as listing persons, insights, and recordings, allow 240 requests per minute and 1,200 per hour. The query endpoint allows 2,400 per hour. Create, update, and delete endpoints allow 480 per minute and 4,800 per hour. The events and values endpoint is tighter at 60 per minute and 300 per hour, and feature flag local evaluation allows 600 per minute. The public event-capture and flag-evaluation endpoints are not rate limited, since they take ingestion and client traffic at volume. Going over a private limit returns a 429.
List endpoints return a page of results with a 'results' array alongside 'next' and 'previous' links. Following the 'next' link until it is null walks the whole set, rather than building the URL by hand. Some endpoints use a cursor in that link rather than a numbered page.
Requests and responses are JSON. The practical cost on the read side is computing the result, since a HogQL query or a heavy insight can scan a large volume of events, rather than a fixed payload size limit. The capture endpoints accept either a single event or a batch in one request.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | Unauthorized | Authentication is missing or the personal API key is invalid or expired. | Send a valid personal API key in the Authorization header as a Bearer token. |
| 403 | Permission denied | The key is valid but its scopes do not cover the endpoint, or it is not scoped to the requested project or organization. | Grant the missing scope, such as insight:read or feature_flag:write, or widen the key's project and organization access. |
| 404 | Not found | The resource does not exist, or the key cannot see it under its current project scope. | Confirm the path, the project or environment id, and that the key reaches that project. |
| 429 | Throttled | A rate limit was exceeded on a private endpoint. The limit applies across the whole organization, not per key. | Slow down and retry after the window resets, using the Retry-After header when present. |
PostHog does not put a dated version number in its API. There is a single, continuously updated API, and breaking changes are announced through the changelog rather than a version string an integration pins.
PostHog does not put a dated version number in its API. There is one continuously updated API, addressed by path under a project or environment id, and breaking changes are announced through the changelog rather than a version header. The dated entries below are notable changes to the API surface, newest first.
PostHog made it possible to turn any saved insight or SQL query into a fast, versioned, authenticated API endpoint, with materialized queries and a configurable cache lifetime. These endpoints reached general availability on this date, and MCP tools for workflows were introduced alongside.
An integration tracks changes through the changelog, since there is no dated version to pin.
PostHog changelog ↗Bollard AI sits between a team's AI agents and PostHog. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.