> For the complete documentation index, see [llms.txt](https://docs.chord.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.chord.co/activate/event-streaming/destinations/analytics/posthog.md).

# PostHog

PostHog is an open-source product analytics platform that helps teams understand how users interact with their web or mobile apps. It combines event tracking, session replays, heatmaps, feature flags and A/B testing in a single platform, so product and engineering teams can analyze behavior, test features and ship improvements faster.

Unlike many analytics tools, PostHog can be self-hosted, giving teams full control over their data and compliance. It is especially popular with teams that want powerful analytics without sending data to third-party servers.

## Getting started

You need your Project API Key to connect to this destination. Find it under [Project Settings](https://app.posthog.com/project/settings) in PostHog.

## Settings

* **Destination Name** (required): a name to tell this destination apart.
* **Project API Key** (required): your PostHog Project API key, found in [Project Settings](https://app.posthog.com/project/settings).
* **Host** (optional): your PostHog host. Defaults to `https://app.posthog.com`.
* **Enable Group Analytics** (optional): lets you run analytics on entities other than single users. Group analytics is not available on the open-source or free cloud plan. See [PostHog pricing](https://posthog.com/pricing). Off by default.
* **Group Type** (optional): the abstract type of whatever your group represents, for example company, team, chat or post. See [groups vs. group types](https://posthog.com/docs/getting-started/group-analytics#groups-vs-group-types). Defaults to `chord_group`.
* **Send Anonymous Events** (optional): send events from anonymous users. If off, only events from identified users are tracked. Off by default.
* **Consent Requirements** (optional): the consent categories a visitor must accept before Chord sends data to this destination. See [Consent](/activate/event-streaming/consent.md).

## Connect

Add **Posthog** from the destination catalog, using the settings above. See [Connect a destination](/activate/event-streaming/connect-a-destination.md) for the full steps.

## Event mapping

Not all Chord tracking events are used downstream in your configured destinations. The most relevant events in the Chord tracking plan are mapped within the destination, relayed and then ingested in [PostHog](https://posthog.com/docs/data/events). The Chord events used by this destination are:

| Chord event      | PostHog event                     | Notes                                                                   |
| ---------------- | --------------------------------- | ----------------------------------------------------------------------- |
| Identify         | *No event, user identification*   | Sets the person's properties from the traits. See Identify events below |
| Page             | `$pageview`                       |                                                                         |
| Screen           | `$screen`                         |                                                                         |
| Group            | *No event, group identification*  | Sent only when **Enable Group Analytics** is on                         |
| Alias            | *No event, merges two identities* | Sent only when the event has both `userId` and `previousId`             |
| All track events | Event name passed as is           | Falls back to the event's `name`, then `Unknown Event`                  |

Events from anonymous visitors, with no `userId`, are skipped unless **Send Anonymous Events** is on. This applies to every event type.

**Who the event belongs to**

PostHog's distinct ID is the first of these that is present:

1. `context.clientIds.posthog.distinctId`
2. `userId`
3. `anonymousId`
4. `traits.email`

**Event properties**

Track, page and screen events carry these properties:

| Chord source (priority order)                                     | PostHog field                                                                                                                       | Notes                                                                                                           |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `context.page`                                                    | `$current_url`, `$host`, `$pathname`, `$referrer`, `$referring_domain`                                                              | `$host`, `$pathname` and `$referring_domain` are worked out from the URLs when `context.page` doesn't have them |
| `context.userAgent`, `context.device.type`                        | `$browser`, `$browser_version`, `$os`, `$os_version`, `$device`, `$device_type`                                                     |                                                                                                                 |
| `context.ip`                                                      | `$ip`                                                                                                                               |                                                                                                                 |
| `context.geo`                                                     | `$geoip_city_name`, `$geoip_country_name`, `$geoip_country_code`, `$geoip_continent_code`, `$geoip_postal_code`, `$geoip_time_zone` |                                                                                                                 |
| `context.screen`                                                  | `$screen_width`, `$screen_height`, `$screen_dpi`                                                                                    |                                                                                                                 |
| `context.campaign`                                                | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`                                                               | `name` becomes `utm_campaign`                                                                                   |
| `name`                                                            | `$screen_name`                                                                                                                      | Screen events only                                                                                              |
| `context.clientIds.posthog.sessionId`                             | `$session_id`                                                                                                                       | Only when present                                                                                               |
| `properties.filters`                                              | `filters_set`                                                                                                                       | Each filter is sent as `type:value`. Only when `filters` is a list                                              |
| Each single-value field in `context`, such as `chord_locale`      | `chord_` followed by the field name                                                                                                 | Fields that hold lists or objects are not sent                                                                  |
| `properties`                                                      | Your own properties                                                                                                                 | All event properties are sent under their own names                                                             |
| `context`, and top-level fields that aren't standard event fields | Raw `context` fields and extra top-level event fields                                                                               | Also sent under their own names, in addition to the rows above                                                  |
| *(hardcoded)* `chord`                                             | `$lib`                                                                                                                              |                                                                                                                 |
| Whether the event has a `userId`                                  | `$process_person_profile`                                                                                                           | `false` for anonymous events                                                                                    |

Each event also carries a unique ID that Chord derives from the event's `messageId`, so PostHog can recognize a repeat of the same event.

**Identify events**

| Chord source (priority order) | PostHog field     | Notes                                          |
| ----------------------------- | ----------------- | ---------------------------------------------- |
| See above                     | Distinct ID       |                                                |
| `traits`                      | Person properties | Plus `$anon_distinct_id`, set to `anonymousId` |

When **Send Anonymous Events** is on and the event has a `userId` and either an `anonymousId` or an email trait, Chord also merges that anonymous identity into the user's profile, so the earlier history is kept together.

**Group events**

When **Enable Group Analytics** is on, group events set the group's properties from the traits, using `groupId` as the group key and **Group Type** as the type. Track, page and screen events that have `context.groupId` are tagged with that group.

## Custom events

Every track event is sent to PostHog under its own name, with all its properties.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.chord.co/activate/event-streaming/destinations/analytics/posthog.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
