PostHog

This guide describes how to add and configure PostHog integration.

PostHog is a product analytics platform that helps teams understand user behavior, analyze product usage, build funnels, and measure retention. Apphud sends subscription lifecycle events and revenue data to PostHog so you can combine monetization metrics with product analytics in a single environment — events are linked to your existing user profiles in PostHog in real time, with no backend implementation required.

What This Integration Enables

This integration connects product behavior with monetization and helps you understand how user actions impact subscriptions, retention, churn, and revenue. With Apphud → PostHog, you can:

  • Track mobile subscription lifecycle in PostHog.
  • Analyze trial → paid conversion funnels.
  • Measure renewals and churn.
  • Build subscription revenue dashboards.
  • Create cohorts by subscription status.

This is useful for mobile apps using subscriptions and product teams using PostHog for analytics.

How to Add Integration?

Step 1 - Install the SDKs

Step 2 - Preparations in PostHog

In your PostHog project, open Settings → Project → General and find the Project token & ID section. Copy the Project token ("Write-only key for use in client libraries").

PostHog - Project token location

If your project is hosted in the EU region or self-hosted, also note your PostHog API URL (see Step 4 below).

Step 3 - Authentication

In Apphud, open Connections → Integrations (the All or Product Analytics tab). Click Add Connection for PostHog and choose a Source — iOS, Android, Flows, or Web-to-App (iOS).

Apphud - Add PostHog connection

Enter the PostHog Project Token (API Key) copied in Step 2 into the Project Token field.

Apphud - PostHog Project Token field

Step 4 - Additional configuration

API URL

Specify the PostHog API URL used for sending server-to-server events. If not provided, the default US Cloud URL https://us.i.posthog.com is used.

Configure the API URL if:

  • Your PostHog project is hosted in the EU region — EU Cloud URL: https://eu.i.posthog.com.
  • You use a self-hosted PostHog instance — enter your PostHog instance URL.
  • You need to send events to a custom PostHog deployment.

Environment

❗️

PostHog has no Sandbox mode for server-to-server

PostHog does not have a dedicated Sandbox mode for server-to-server integrations. If you send both Production and Sandbox events through the same connection, all of them end up in the same PostHog reports.

To keep test and live events separate, create a new PostHog project and configure a separate Apphud integration that sends only Sandbox events to it.

Revenue

PostHog-specific revenue option:

  • Send Revenue Properties — when ON, Apphud sends product ID, purchase price, and currency to PostHog as event properties when available.

    Apphud - PostHog Revenue configuration

Generic Send sales as proceeds is described once on Integrations overview → Configuration tab.

Set up filters (optional)

Navigate to Filters tab. Set up filters if needed as described on Integrations overview → Filters tab.

Step 5 - Set up Events list

Open the Events tab of the configuration. You can customize event names or disable specific events. See Events Cheat Sheet for the list of supported events and their properties.

Step 6 - Test connection (optional)

Save the connection.

To send a test event, click the Test connection button on the integration configuration page, enter an Event ID or Transaction ID, and click Send test event. If the configuration is accurate, you'll see a success message and integration logs.

Apphud - PostHog test event result

Step 7 - Enable and save

Turn the integration on by switching the Enable integration control, and click Save.

Match user IDs

Initialize both SDKs and match Apphud's User ID to PostHog's distinct_id:

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    Apphud.start(apiKey: "YOUR_API_KEY")
    Apphud.setDelegate(self)

    PostHogSDK.shared.setup(apiKey: "POSTHOG_API_KEY")
    PostHogSDK.shared.identify(Apphud.userID())

    return true
}

func apphudDidChangeUserID(_ userID: String) {
    PostHogSDK.shared.identify(userID)
}
Apphud.start(apiKey = "YOUR_API_KEY")
PostHog.setup(this, "POSTHOG_API_KEY")
PostHog.identify(Apphud.userID())
Future<void> initPosthog() async {
  final userId = await Apphud.userID();
  await Posthog().identify(userId);
}

@override
Future<void> apphudDidChangeUserID(String userId) async {
  await Posthog().identify(userId);

Events Cheat Sheet

Here is a list of events and their parameters sent to PostHog.

📘

Note

You can read more about subscription events here and about parameters here.

Trial

Trial period started

Default event name: [Apphud] trial_started

Revenue Parameters:

  • product_id: String
  • unit: String
  • units_count: Integer

Successful conversion from trial period to regular subscription

Default event name: [Apphud] trial_converted

Revenue Parameters:

  • product_id: String
  • local_price: Float
  • currency: String
  • usd_price: Float

Cancellations

Trial Canceled

Default event name: [Apphud] trial_canceled

Revenue Parameters:

  • product_id: String

Subscription Canceled

Default event name: [Apphud] subscription_canceled

Revenue Parameters:

  • product_id: String

Regular

Subscription started

Default event name: [Apphud] subscription_started

Revenue Parameters:

  • product_id: String
  • local_price: Float
  • currency: String
  • usd_price: Float

Subscription renewed

Default event name: [Apphud] subscription_renewed

Revenue Parameters:

  • product_id: String
  • local_price: Float
  • currency: String
  • usd_price: Float

Subscription refunded

Default event name: [Apphud] subscription_refunded

Revenue Parameters:

  • product_id: String
  • local_price: Float
  • currency: String
  • usd_price: Float

Other Events

Non-renewing purchase

Default event name: [Apphud] non_renewing_purchase

Revenue Parameters:

  • product_id: String
  • local_price: Float
  • currency: String
  • usd_price: Float

Event Payload Structure (Apphud → PostHog)

Apphud sends subscription events to PostHog using a server-to-server JSON payload. Each event contains event metadata, user identifiers, event properties, and user profile updates.

Payload Overview

FieldDescription
api_keyPostHog Project API key / Project token
eventEvent name, as configured in Apphud integration
distinct_idPostHog user identifier received as a result of matching
timestampEvent time (ISO 8601)
platformApp platform (iOS / Android / Web)
environmentApp environment (production / sandbox)
propertiesEvent parameters and user property updates

Event Properties

Event-specific parameters are included inside the properties object. The exact set of properties depends on event type, platform, and integration configuration. These may include:

  • Product information
  • Revenue data (if configured to be included)
  • Custom parameters
  • Device and OS metadata

Optional properties are sent only when available. If a value does not exist for a given event, the property is not included in the payload.

User Properties

Apphud updates PostHog user profiles on each event using the $set object. This ensures user-level monetization and subscription status are always up to date.

Monetization Properties

PropertyTypeDescription
[Apphud] total_spentFloatTotal user spend
[Apphud] payingBooleanWhether user is a paying customer
[Apphud] payments_countIntegerNumber of successful payments

Subscription Status by Product Group

Apphud sends subscription state separately for each product group. This allows analyzing subscriptions across multiple platforms, stores, and product lines.

PropertyTypeDescription
[Apphud] status-{group}StringSubscription state (trial / regular / none)
[Apphud] autorenew-{group}BooleanAuto-renew status
📘

Note

More information about user properties can be found here.

Example Payload

{
  "api_key": "<POSTHOG_PROJECT_API_KEY>",
  "event": "[Apphud] subscription_renewed",
  "distinct_id": "66fbbd89-7c2b-45ff-aac3-de358b93c9a6",
  "timestamp": "2026-03-06T10:31:02.000Z",
  "platform": "iOS",
  "environment": "sandbox",
  "properties": {
    "$set": {
      "[Apphud] total_spent": 115.92,
      "[Apphud] paying": true,
      "[Apphud] payments_count": 8,
      "[Apphud] status-stripe": "regular",
      "[Apphud] autorenew-stripe": true
    }
  }
}

FAQ

All events show Pending for the PostHog integration. Why?

If Apphud hasn't received a PostHog User ID, events cannot be sent to PostHog. Ensure that the user-matching code is shipped in the current production app version. See Step 1 — Match User IDs.

Can I separate test and production data in PostHog?

Yes. Provide separate API keys (and corresponding integrations) for production and test PostHog projects. See Environment for why this is necessary.