• Product
  • Pricing
  • Docs
  • Using PostHog
  • Community
  • Company
  • Login
  • Docs

  • Overview
    • Quickstart with PostHog Cloud
    • Overview
      • AWS
      • Azure
      • DigitalOcean
      • Google Cloud Platform
      • Hobby
      • Other platforms
      • Instance settings
      • Environment variables
      • Securing PostHog
      • Monitoring with Grafana
      • Running behind a proxy
      • Configuring email
      • Helm chart configuration
      • Deploying ClickHouse using Altinity.Cloud
      • Configuring Slack
      • Overview
        • Overview
        • Upgrade notes
        • Overview
        • 0001-events-sample-by
        • 0002_events_sample_by
        • 0003_fill_person_distinct_id2
        • ClickHouse
          • Backup
          • Kafka Engine
          • Resize disk
          • Restore
          • Vertical scaling
          • Horizontal scaling (Sharding & replication)
        • Kafka
          • Resize disk
          • Log retention
        • PostgreSQL
          • Resize disk
          • Troubleshooting long-running migrations
        • Plugin server
        • MinIO
        • Redis
        • Zookeeper
      • Disaster recovery
    • Troubleshooting and FAQs
    • Architecture
    • Managing hosting costs
    • EU-only hosting
    • Overview
    • Ingest live data
    • Ingest historical data
    • Identify users
    • User properties
    • Deploying a reverse proxy
    • Libraries
    • Badge
      • Snippet installation
      • Android
      • iOS
      • JavaScript
      • Flutter
      • React Native
      • Browser Extensions
      • Elixir
      • Go
      • Java
      • Node.js
      • PHP
      • Python
      • Ruby
      • Docusaurus v2
      • Gatsby
      • Google Tag Manager
      • Next.js
      • Nuxt.js
      • Retool
      • RudderStack
      • Segment
      • Sentry
      • Slack
      • Shopify
      • WordPress
      • Message formatting
      • Microsoft Teams
      • Slack
      • Discord
    • To another self-hosted instance
    • To PostHog from Amplitude
    • Between Cloud and self-hosted
    • Overview
    • Troubleshooting
      • Overview
      • Tutorial
      • TypeScript types
      • Developer reference
        • Amazon Kinesis Import
        • BitBucket Release Tracker
        • Braze Import
        • Event Replicator
        • GitHub Release Tracker
        • GitHub Star Sync
        • GitLab Release Tracker
        • Heartbeat
        • Ingestion Alert
        • Email Scoring
        • n8n Connector
        • Orbit Connector
        • Redshift Import
        • Segment Connector
        • Shopify Connector
        • Twitter Followers Tracker
        • Zendesk Connector
        • Airbyte Exporter
        • Amazon S3 Export
        • BigQuery Export
        • Customer.io Connector
        • Databricks Export
        • Engage Connector
        • GCP Pub/Sub Connector
        • Google Cloud Storage Export
        • Hubspot Connector
        • Intercom Connector
        • Migrator 3000
        • PagerDuty Connector
        • PostgreSQL Export
        • Redshift Export
        • RudderStack Export
        • Salesforce Connector
        • Sendgrid Connector
        • Sentry Connector
        • Snowflake Export
        • Twilio Connector
        • Variance Connector
        • Zapier Connector
        • Downsampler
        • Event Sequence Timer
        • First Time Event Tracker
        • Property Filter
        • Property Flattener
        • Schema Enforcer
        • Taxonomy Standardizer
        • Unduplicator
        • Automatic Cohort Creator
        • Currency Normalizer
        • GeoIP Enricher
        • Timestamp Parser
        • URL Normalizer
        • User Agent Populator
    • Overview
    • POST-only public endpoints
    • Actions
    • Annotations
    • Cohorts
    • Dashboards
    • Event definitions
    • Events
    • Experiments
    • Feature flags
    • Funnels
    • Groups
    • Groups types
    • Insights
    • Invites
    • Members
    • Persons
    • Plugin configs
    • Plugins
    • Projects
    • Property definitions
    • Session recordings
    • Trends
    • Users
    • Data model
    • Overview
    • GDPR guidance
    • HIPAA guidance
    • CCPA guidance
    • Data egress & compliance
    • Overview
    • Code of conduct
    • Recognizing contributions
  • Using PostHog

  • Table of contents
      • Dashboards
      • Funnels
      • Group Analytics
      • Insights
      • Lifecycle
      • Path analysis
      • Retention
      • Stickiness
      • Trends
      • Heatmaps
      • Session Recording
      • Correlation Analysis
      • Experimentation
      • Feature Flags
      • Actions
      • Annotations
      • Cohorts
      • Data Management
      • Events
      • Persons
      • Sessions
      • UTM segmentation
      • Team collaboration
      • Organizations & projects
      • Settings
      • SSO & SAML
      • Toolbar
      • Notifications & alerts
  • Tutorials
    • All tutorials
    • Actions
    • Apps
    • Cohorts
    • Dashboards
    • Feature flags
    • Funnels
    • Heatmaps
    • Path analysis
    • Retention
    • Session recording
    • Trends
  • Support
  • Docs

  • Overview
    • Quickstart with PostHog Cloud
    • Overview
      • AWS
      • Azure
      • DigitalOcean
      • Google Cloud Platform
      • Hobby
      • Other platforms
      • Instance settings
      • Environment variables
      • Securing PostHog
      • Monitoring with Grafana
      • Running behind a proxy
      • Configuring email
      • Helm chart configuration
      • Deploying ClickHouse using Altinity.Cloud
      • Configuring Slack
      • Overview
        • Overview
        • Upgrade notes
        • Overview
        • 0001-events-sample-by
        • 0002_events_sample_by
        • 0003_fill_person_distinct_id2
        • ClickHouse
          • Backup
          • Kafka Engine
          • Resize disk
          • Restore
          • Vertical scaling
          • Horizontal scaling (Sharding & replication)
        • Kafka
          • Resize disk
          • Log retention
        • PostgreSQL
          • Resize disk
          • Troubleshooting long-running migrations
        • Plugin server
        • MinIO
        • Redis
        • Zookeeper
      • Disaster recovery
    • Troubleshooting and FAQs
    • Architecture
    • Managing hosting costs
    • EU-only hosting
    • Overview
    • Ingest live data
    • Ingest historical data
    • Identify users
    • User properties
    • Deploying a reverse proxy
    • Libraries
    • Badge
      • Snippet installation
      • Android
      • iOS
      • JavaScript
      • Flutter
      • React Native
      • Browser Extensions
      • Elixir
      • Go
      • Java
      • Node.js
      • PHP
      • Python
      • Ruby
      • Docusaurus v2
      • Gatsby
      • Google Tag Manager
      • Next.js
      • Nuxt.js
      • Retool
      • RudderStack
      • Segment
      • Sentry
      • Slack
      • Shopify
      • WordPress
      • Message formatting
      • Microsoft Teams
      • Slack
      • Discord
    • To another self-hosted instance
    • To PostHog from Amplitude
    • Between Cloud and self-hosted
    • Overview
    • Troubleshooting
      • Overview
      • Tutorial
      • TypeScript types
      • Developer reference
        • Amazon Kinesis Import
        • BitBucket Release Tracker
        • Braze Import
        • Event Replicator
        • GitHub Release Tracker
        • GitHub Star Sync
        • GitLab Release Tracker
        • Heartbeat
        • Ingestion Alert
        • Email Scoring
        • n8n Connector
        • Orbit Connector
        • Redshift Import
        • Segment Connector
        • Shopify Connector
        • Twitter Followers Tracker
        • Zendesk Connector
        • Airbyte Exporter
        • Amazon S3 Export
        • BigQuery Export
        • Customer.io Connector
        • Databricks Export
        • Engage Connector
        • GCP Pub/Sub Connector
        • Google Cloud Storage Export
        • Hubspot Connector
        • Intercom Connector
        • Migrator 3000
        • PagerDuty Connector
        • PostgreSQL Export
        • Redshift Export
        • RudderStack Export
        • Salesforce Connector
        • Sendgrid Connector
        • Sentry Connector
        • Snowflake Export
        • Twilio Connector
        • Variance Connector
        • Zapier Connector
        • Downsampler
        • Event Sequence Timer
        • First Time Event Tracker
        • Property Filter
        • Property Flattener
        • Schema Enforcer
        • Taxonomy Standardizer
        • Unduplicator
        • Automatic Cohort Creator
        • Currency Normalizer
        • GeoIP Enricher
        • Timestamp Parser
        • URL Normalizer
        • User Agent Populator
    • Overview
    • POST-only public endpoints
    • Actions
    • Annotations
    • Cohorts
    • Dashboards
    • Event definitions
    • Events
    • Experiments
    • Feature flags
    • Funnels
    • Groups
    • Groups types
    • Insights
    • Invites
    • Members
    • Persons
    • Plugin configs
    • Plugins
    • Projects
    • Property definitions
    • Session recordings
    • Trends
    • Users
    • Data model
    • Overview
    • GDPR guidance
    • HIPAA guidance
    • CCPA guidance
    • Data egress & compliance
    • Overview
    • Code of conduct
    • Recognizing contributions
  • Using PostHog

  • Table of contents
      • Dashboards
      • Funnels
      • Group Analytics
      • Insights
      • Lifecycle
      • Path analysis
      • Retention
      • Stickiness
      • Trends
      • Heatmaps
      • Session Recording
      • Correlation Analysis
      • Experimentation
      • Feature Flags
      • Actions
      • Annotations
      • Cohorts
      • Data Management
      • Events
      • Persons
      • Sessions
      • UTM segmentation
      • Team collaboration
      • Organizations & projects
      • Settings
      • SSO & SAML
      • Toolbar
      • Notifications & alerts
  • Tutorials
    • All tutorials
    • Actions
    • Apps
    • Cohorts
    • Dashboards
    • Feature flags
    • Funnels
    • Heatmaps
    • Path analysis
    • Retention
    • Session recording
    • Trends
  • Support
  • Docs
  • API
  • POST-only public endpoints

POST-only public endpoints

Last updated: Jul 21, 2022

On this page

  • Sending events
  • Single event
  • Batch events
  • Sample requests
  • Alias
  • Capture
  • Identify
  • Page
  • Screen
  • Responses
  • Status code: 200
  • Responses
  • Status code: 400
  • Responses
  • Status code: 401
  • Responses
  • Status code: 503 (Deprecated)
  • Responses
  • Invalid events
  • Feature flags
  • /decide
  • Example request & response: /decide v2
  • Request
  • Response
  • Example request & response: /decide v1 (legacy)
  • Request
  • Response
  • Reading data from PostHog

Update: These endpoints can now be accessed with either your Team API key or your personal API key.

As explained in our API overview page, PostHog provides two different APIs.

This page refers to our public endpoints, which use the same API key as the PostHog snippet. The endpoints documented here are used solely with POST requests, and will not return any sensitive data from your PostHog instance.

Note: For this API, you should use your 'Project API Key' from the 'Project' page in PostHog. This is the same key used in your frontend snippet.

Sending events

To send events to PostHog, you can use any of our libraries or any Mixpanel library by changing the api_host setting to the address of your instance.

If you'd prefer to do the requests yourself, you can send events in the following format:

Single event

Note: Timestamp is optional. If not set, it'll automatically be set to the current time.

POST https://[your-instance].com/capture/
Content-Type: application/json
Body:
{
"api_key": "<ph_project_api_key>",
"event": "[event name]",
"properties": {
"distinct_id": "[your users' distinct id]",
"key1": "value1",
"key2": "value2"
},
"timestamp": "[optional timestamp in ISO 8601 format]"
}

Batch events

You can send multiple events in one go with the Batch API.

There is no limit on the number of events you can send in a batch, but the entire request body must be less than 20MB by default (see API overview).

Note: Timestamp is optional. If not set, it'll automatically be set to the current time.

POST https://[your-instance].com/capture/
Content-Type: application/json
Body:
{
"api_key": "<ph_project_api_key>",
"batch": [
{
"event": "[event name]",
"properties": {
"distinct_id": "[your users' distinct id]",
"key1": "value1",
"key2": "value2"
},
"timestamp": "[optional timestamp in ISO 8601 format]"
},
...
]
}

Sample requests

Here are some sample curl queries for each event type. Do note that you need to insert your API key into the api_key field.

Additionally, if you're self-hosting, you'll have to substitute https://app.posthog.com/ for the URL of your instance.

Alias

curl -v -L --header "Content-Type: application/json" -d '{
"api_key": "<ph_project_api_key>",
"properties": {
"distinct_id": "123",
"alias": "456"
},
"timestamp": "2020-08-16 09:03:11.913767",
"context": "{}",
"type": "alias",
"event": "$create_alias"
}' https://app.posthog.com/batch/

Capture

curl -v -L --header "Content-Type: application/json" -d '{
"api_key": "<ph_project_api_key>",
"properties": {},
"timestamp": "2020-08-16 09:03:11.913767",
"context": {},
"distinct_id": "1234",
"type": "capture",
"event": "$event",
"messageId": "1234"
}' https://app.posthog.com/batch/

Identify

curl -v -L --header "Content-Type: application/json" -d '{
"api_key": "<ph_project_api_key>",
"timestamp": "2020-08-16 09:03:11.913767",
"context": {},
"type": "screen",
"distinct_id": "1234",
"$set": {},
"event": "$identify",
"messageId": "123"
}' https://app.posthog.com/batch/

Page

curl -v -L --header "Content-Type: application/json" -d '{
"api_key": "<ph_project_api_key>",
"properties": {},
"timestamp": "2020-08-16 09:03:11.913767",
"category": "some category",
"context": {},
"distinct_id": "1234",
"type": "page",
"event": "$page",
"name": "a page",
"messageId": "123"
}' https://app.posthog.com/batch/

Screen

curl -v -L --header "Content-Type: application/json" -d '{
"api_key": "<ph_project_api_key>",
"properties": {},
"timestamp": "2020-08-16 09:03:11.913767",
"category": "some category",
"context": {},
"distinct_id": "1234",
"type": "screen",
"event": "$screen",
"name": "a page",
"messageId": "123"
}' https://app.posthog.com/batch/

Responses

Status code: 200

Responses
{
status: 1
}

Meaning: A 200: OK response means we have successfully received the payload, it is in the correct format, and the project API key (token) is valid. It does not imply that events are valid and will be ingested. As mentioned under Invalid events, certain event validation errors may cause an event not to be ingested.

Status code: 400

Responses
{
type: 'validation_error',
code: 'invalid_project',
detail: 'Invalid Project ID.',
attr: 'project_id'
}

Meaning: We were unable to determine the project to associate the events with.

Status code: 401

Responses
{
type: 'authentication_error',
code: 'invalid_api_key',
detail: 'Project API key invalid. You can find your project API key in PostHog project settings.',
}

Meaning: The token/API key you provided is invalid.


{
type: 'authentication_error',
code: 'invalid_personal_api_key',
detail: 'Invalid Personal API key.',
}

Meaning: The personal API key you used for authentication is invalid.

Status code: 503 (Deprecated)

Responses
{
type: 'server_error',
code: 'fetch_team_fail',
detail: 'Unable to fetch team from database.'
}

Meaning: (Deprecated) This error will only occur in self-hosted Postgres instances if the database becomes unavailable. On ClickHouse-backed instances database failures cause events to be added to a dead letter queue, from which they can be recovered.

Invalid events

We perform basic validation on the payload and project API key (token), returning a failure response if an error is encountered.

However, we will not return an error to the client when the following happens:

  • An event does not have a name
  • An event does not have the distinct_id field set
  • The distinct_id field of an event has an empty value

The three cases above will cause the event to not be ingested, but you will still receive a 200: OK response from us.

This approach allows us to process events asynchronously if necessary, ensuring reliability and low latency for our event ingestion endpoints.

Feature flags

PostHog offers support for feature flags, and you can use our APIs to create and make use of feature flags. However, it is important to note that while creating a feature flag is a private action that only your team should be able to perform, checking if a feature flag is active is not.

As such, to create feature flags, you will need to use another endpoint, which we're currently still documenting. However, to check if a feature flag is enabled, you can use the following endpoint:

/decide

/decide is the endpoint used to determine if a given flag is enabled for a certain user or not. This endpoint is used by our JavaScript Library's methods for feature flags.

To get the feature flags that are enabled for a given user, you will need to perform the following request:

POST <ph_instance_address>/decide/ # e.g. https://posthog.yourcompany.com for self-hosted users
Content-Type: application/json
Body:
{
"api_key": "<ph_project_api_key>",
"distinct_id": "[user's distinct id]"
}

Example request & response: /decide v2

/decide version 2 introduces support for multivariate feature flags and has a slightly different schema for the response. posthog-js version 1.13 and up will use version 2 of the decide endpoint by default.

Request

curl -v -L --header "Content-Type: application/json" -d ' {
"api_key": "<ph_project_api_key>",
"distinct_id": "1234"
}' https://app.posthog.com/decide?v=2

Response

{
"config": {
"enable_collect_everything": true
},
"editorParams": {},
"isAuthenticated": false,
"supportedCompression": [
"gzip",
"lz64"
],
"featureFlags": {
"my-awesome-flag": true,
"my-awesome-flag-2": true,
"my-multivariate-flag": "some-string-value"
}
}

Example request & response: /decide v1 (legacy)

/decide version 1 is still the default if the query parameter v is not specified, although the latest posthog-js library no longer uses version 1 of the decide endpoint, and we recommend using version 2 as described above.

Request

curl -v -L --header "Content-Type: application/json" -d ' {
"api_key": "<ph_project_api_key>",
"distinct_id": "1234"
}' https://app.posthog.com/decide?v=1

Response

{
"config": {
"enable_collect_everything": true
},
"editorParams": {},
"isAuthenticated": false,
"supportedCompression": [
"gzip",
"lz64"
],
"featureFlags": [
"my-awesome-flag-1",
"my-awesome-flag-2",
"my-multivariate-flag"
]
}

From this response, if you are looking to use feature flags in your backend, you will most likely need only the values for the featureFlags key, which indicate what flags are on for the user with the distinct ID you provided. These flags persist for users (unless you change your flag settings), so you can cache them rather than send a request to the endpoint each time if you so wish.

Note that if a multivariate feature flag is enabled for a given user, it will still show up in featureFlags under decide version 1, but its value will only be accessible when using decide version 2.

Reading data from PostHog

We have another set of APIs to read/modify anything in PostHog. See our API documentation for more information.

Also, feel free to reach out in the PostHog Users Slack if you'd like help with the API.

Questions?

Was this page useful?

Authors

  • pjhul
    pjhul
  • Tim Glaser
    Tim Glaser
  • samwinslow
    samwinslow

Share

Jump to:

  • Single event
  • Batch events
  • Sample requests
  • Alias
  • Capture
  • Identify
  • Page
  • Screen
  • Responses
  • Invalid events
  • Example request & response: /decide v2
  • Example request & response: /decide v1 (legacy)
  • Questions?
  • Edit this page
  • Raise an issue
  • Toggle content width
  • Toggle dark mode
  • About
  • Blog
  • Newsletter
  • Careers
  • Support
  • Contact sales

Product OS suite

Product overview

Analytics
  • Funnels
  • Trends
  • Paths

Pricing

Features
  • Session recording
  • Feature flags
  • Experimentation
  • Heatmaps

Customers

Platform
  • Correlation analysis
  • Collaboration
  • Apps

Community

Discussion
  • Questions?
  • Slack
  • Issues
  • Contact sales
Get involved
  • Roadmap
  • Contributors
  • Merch
  • PostHog FM
  • Marketplace

Docs

Getting started
  • PostHog Cloud
  • Self-hosted
  • Compare options
  • Tutorials
  • PostHog on GitHub
Install & integrate
  • Installation
  • Docs
  • API
  • Apps
User guides
  • Cohorts
  • Funnels
  • Sessions
  • Data
  • Events

Company

About
  • Our story
  • Team
  • Handbook
  • Investors
  • Careers
Resources
  • FAQ
  • Ask a question
  • Blog
  • Press
  • Merch
  • YouTube
© 2022 PostHog, Inc.
  • Code of conduct
  • Privacy
  • Terms