openapi: 3.0.0 info: version: '1.0.0' title: PostHog Capture API description: | > 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. Note that this specification is an attempt to capture some of the details on the [POST-only public endpoints documentation](https://posthog.com/docs/api/post-only-endpoints) but in a format that we can easily use to validate the correctness of our API implementation. It is not a complete specification of the API, and should not be used as such. It will hopefully become such a document, but is currently a work in progress. ### TODOs 1. add autocapture properties schema 1. add performance event properties schema 1. add session recording event properties schema 1. add any specifications we want to include for other endpoints and GET requests e.g. `GET /e/` and `POST /engage/` endpoints. paths: /capture/: post: summary: Sending an event description: | > Note: Timestamp is optional. If not set, it'll automatically be set to the current time. Capture an event. Events are the core of PostHog, and are what you use to track user behavior, and then analyze and visualize in PostHog. parameters: - in: query name: ip schema: type: string format: ipv4 description: | The IP address of the user. This is used to geolocate the user. - in: query name: compression description: | The compression method used to compress the request body. schema: type: string enum: - gzip-js - gzip - lz64 responses: '200': description: | On successful capture of an event or events, we notify you with a 200 response. A 200 response guarantees that the event was persisted by PostHog, but does not guarantee that it will be processed successfully. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureResponse' '401': description: | If you send an invalid API key, we will return a 401 response. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureUnauthenticatedResponse' '400': description: | If you send an invalid request, we will return a 400 response. This can happen if you send an invalid JSON payload among other things. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureClientErrorResponse' requestBody: content: application/json: schema: $ref: '#/components/schemas/EventCaptureRequest' example: { 'api_key': '', 'event': '[event name]', 'properties': { 'distinct_id': "[your users' distinct id]", 'key1': 'value1', 'key2': 'value2' }, 'timestamp': '[optional timestamp in ISO 8601 format]', } multipart/form-data: schema: $ref: '#/components/schemas/EventCaptureRequest' text/plain: examples: gzip_event: summary: | Gzipped request body as per the application/json schema. description: | Provides a method to capture events. Events are the core of PostHog, and are what you use to track user behavior, and then analyze and visualize in PostHog. /batch/: post: summary: Sending multiple events description: | 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. parameters: - in: query name: ip schema: type: string format: ipv4 description: | The IP address of the user. This is used to geolocate the user. - in: query name: compression description: | The compression method used to compress the request body. schema: type: string enum: - gzip-js - gzip - lz64 responses: '200': description: | On successful capture of an event or events, we notify you with a 200 response. A 200 response guarantees that the event was persisted by PostHog, but does not guarantee that it will be processed successfully. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureResponse' '401': description: | If you send an invalid API key, we will return a 401 response. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureUnauthenticatedResponse' '400': description: | If you send an invalid request, we will return a 400 response. This can happen if you send an invalid JSON payload among other things. content: application/json: schema: $ref: '#/components/schemas/EventsCaptureClientErrorResponse' requestBody: content: application/json: schema: $ref: '#/components/schemas/EventsCaptureRequest' example: { 'api_key': '', 'batch': [ { 'event': '[event name]', 'properties': { 'distinct_id': "[your users' distinct id]", 'key1': 'value1', 'key2': 'value2', }, 'timestamp': '[optional timestamp in ISO 8601 format]', }, ], } multipart/form-data: schema: $ref: '#/components/schemas/EventsCaptureRequest' text/plain: examples: gzip_event: summary: | Gzipped request body as per the application/json schema. description: | Provides a method to capture events. Events are the core of PostHog, and are what you use to track user behavior, and then analyze and visualize in PostHog. components: schemas: Event: type: object additionalProperties: false properties: event: type: string offset: type: number distinct_id: type: string $distinct_id: type: string $token: type: string project_id: type: integer api_key: type: string timestamp: type: string format: date-time uuid: type: string format: uuid type: type: string $set: $ref: '#/components/schemas/SetPersonProperties' $set_once: $ref: '#/components/schemas/SetOncePersonProperties' properties: type: object properties: $set: $ref: '#/components/schemas/SetPersonProperties' $set_once: $ref: '#/components/schemas/SetOncePersonProperties' additionalProperties: true SetPersonProperties: type: object description: | Set person property to a given values. If the property does not exist, it will be set. If the property already exists, it will be updated to the new value. The type of the property will be inferred from the value. additionalProperties: true example: $set: country: UK city: Cambridge SetOncePersonProperties: type: object description: | Set person property to a given value, but only if it is not currently set. It will not override existing values. The type of the property will be inferred from the value. example: $set_once: initial_referrer: https://google.com EventCaptureRequest: $ref: '#/components/schemas/Event' EventsCaptureRequest: anyOf: - type: object required: - 'batch' properties: api_key: type: string description: | The API key for your project. You can find this in your project settings. batch: type: array items: $ref: '#/components/schemas/Event' - type: object required: - 'data' properties: api_key: type: string description: | The API key for your project. You can find this in your project settings. data: oneOf: - type: array items: $ref: '#/components/schemas/Event' - type: string description: | A JSON stringified array of events. Optionally base64 encoded. - type: array items: $ref: '#/components/schemas/Event' EventsCaptureResponse: type: object properties: status: type: number enum: [0, 1] example: 1 EventsCaptureClientErrorResponse: type: object required: - 'type' - 'code' - 'detail' properties: type: type: string enum: ['validation_error'] code: type: string example: 'invalid_input' detail: type: string example: 'Malformed request' attr: type: string example: 'api_key' EventsCaptureUnauthenticatedResponse: type: object required: - 'type' - 'code' - 'detail' properties: type: type: string enum: ['authentication_error'] code: type: string example: 'invalid_token' detail: type: string example: 'Invalid API key'