Skip to content

Bugs and session replays from PostHog

Your PostHog already sees the errors your users hit, and records what they did before them. Connect it to an app and those errors arrive as bugs with the replay attached — and any bug, however it was raised, can point at the session that shows it.

The shape of it

  • Bugs in. A destination in PostHog posts the events you pick — every captured exception by default — to a URL made for the app. Each becomes a bug on the app with what went wrong, the page or screen, the browser, OS and app version, who it happened to, and links to the session replay, the error-tracking issue and the event.
  • Replays on any bug. A tester can paste a replay link onto any bug on a connected app, or, for a bug an outside reporter sent, look up their latest recorded session. The bug shows Watch the session (PostHog).

A bug from PostHog is the same as one raised in the app: it is filed in Linear, Jira, GitHub or GitLab if the app is connected, Slack hears of it, it can be given a priority and people, and it counts towards Free's monthly allowance of issues. This is the integration with your PostHog; it is on every plan.

Connect an app

  1. In PostHog, go to Settings → Personal API keys → Create personal API key. Limit it to the project, and give it read access to query, session_recording and error_tracking (and project, if you want the project's name shown). It needs nothing it can write with.
  2. In qarunbook, open the app, choose Configure, then the Integrations tab, and find PostHog. You need to be an admin of the app.
  3. Pick US Cloud, EU Cloud or Self-hosted (your instance's https address), give the project id — the number after /project/ in PostHog's address bar — and the key, and Connect. The key is checked against PostHog before anything is saved.

The key is stored encrypted and never shown again — the card shows only its last four characters. A self-hosted address must be reachable from the internet over https: addresses inside a private network are refused.

Send bugs from PostHog

Bugs from PostHog are for apps in live mode, where a bug does not need a check. Once the app is connected, the card shows a webhook URL and a signing secret. In PostHog:

  1. Open Data pipelines → Destinations → New destination and choose HTTP Webhook.
  2. Paste the webhook URL from the card, and leave the method as POST.
  3. Set the JSON body to PostHog's default with the project added:
JSON body
{
  "event": "{event}",
  "person": "{person}",
  "project": "{project}"
}
  1. Optionally paste the card's signing secret into Signing secret. PostHog then signs each request the Standard Webhooks way, and from the first signed delivery on, unsigned ones are refused.
  2. Under the destination's filters, choose the same events the card listens for, so PostHog only sends those.
  3. Create it and use PostHog's test button. The card shows Last delivery and what happened to it — a test event that is not one you listen for reads ignored, which still proves the URL works.

The URL is the permission: anyone holding it can raise bugs on the app. Keep it in PostHog, and use Regenerate URL and secret if it ends up anywhere else — the old URL stops at once.

What becomes the bug

A bug from an exception
TypeError: Cannot read properties of undefined (reading 'total')
at handleSubmit (src/checkout.tsx:42)

PostHog event $exception on https://shop.example.com/checkout
On: Chrome 129 · Mac OS X 14.5 · Desktop · app 2.3.1
Person: user_8f3a21

Watch the session (PostHog): https://us.posthog.com/project/12345/replay/0192a1b2-…
Error tracking issue: https://us.posthog.com/project/12345/error_tracking/0192a1b2-…
Event in PostHog: https://us.posthog.com/project/12345/events/0192a1b2-…
  • For an exception, the first line is its type and message, then the frame of your own code it was thrown from. For any other event, it is the event's name and its message or description property when it has one.
  • Where: $current_url, or $screen_name on mobile. On what: browser, OS, device and $app_version.
  • A replay link when the event had a $session_id, the error-tracking issue when PostHog grouped it into one, and the event itself.
  • Every bug from PostHog affects the platforms you pick on the card, or every platform if you pick none.

Which events

  • $exception — every exception PostHog captures. The default.
  • $error_tracking_issue_created and $error_tracking_issue_reopened — one per error-tracking issue rather than one per exception, if you would rather hear of new issues than of every occurrence. PostHog sends these from error tracking's own alerts rather than from Data pipelines: add an alert there that posts to a webhook, with the same URL and body.
  • Your own, such as bug_reported from an in-app “Report a problem” button. Each one is a new bug.
  • $rageclick and $dead_click — frustration signals, one bug per page per session.

Keeping the noise down

  • Treat repeats as one bug for an hour up to seven days (a day by default). The same exception is recognised by its error-tracking issue, else its fingerprint, else its type and message; it raises one bug, however many users hit it.
  • At most, bugs an hour caps what one connection can raise — 30 by default. Past it, deliveries are dropped until the hour is up.
  • An event PostHog delivers twice is logged once.
  • On Free, once the month's issues are used up, deliveries are not logged until the allowance comes back.

Replays on any bug

On a connected app, every bug has Attach replay for anyone with tester access. Paste the replay's link from PostHog (…/project/12345/replay/…) or just its session id. It must come from the connected project; a link from another project or another PostHog is refused.

When the bug came from someone outside the team — by email, through the API, or from PostHog itself — and qarunbook knows their PostHog id or email, Find their latest session looks up their most recent recording from the last 30 days. You see when it was and how long, and attach it if it is the right one.

People and privacy

By default a bug names the person by their PostHog id or display name, and never by email: if their id is itself an email, it is hidden. Turn on Keep the person's email on the bug to write the email down when PostHog sends one — it is then stored as the bug's reporter and returned by the REST API. Nothing is ever written to PostHog: the key is only used to check the connection and to look up a reporter's sessions, by their PostHog id or email, when someone asks.

Something unclear or missing? Write to hello@qarunbook.com.