PostHog Funnel Analytics
Goal
Track core funnel behavior reliably in PostHog:
- page view
- signup/auth
- project create
- checkout start / success / fail
Configuration
Required env vars:
POSTHOG_API_KEY— PostHog project API key (phc_...) for capturePOSTHOG_HOST— ingest host (https://us.i.posthog.comorhttps://eu.i.posthog.com)
Djass wires both frontend and backend capture through these settings. No PostHog secret is hardcoded in source.
Event mapping
| Funnel Step | Event Name | Where Emitted | Key Properties |
|---|---|---|---|
| Page view | $pageview |
PostHog JS snippet (capture_pageview: true) in base_landing.html / base_app.html |
standard PostHog page properties |
| Signup | user_signed_up |
apps/pages/views.py (SignupTrackingMixin._track_signup) |
signup_method, funnel_step=signup_completed |
| Auth/login | user_authenticated |
apps/core/signals.py (track_user_login) |
auth_method, funnel_step=auth_completed, entrypoint=ui |
| Auth failure | user_auth_failed |
apps/core/signals.py (track_user_login_failed), apps/api/views.py (create_project_v1 insufficient scope) |
reason, auth_method (UI only), required_scope (API scope fail), funnel_step=auth_failed, entrypoint |
| Project create | project_created |
apps/core/views.py (create_project), apps/api/views.py (create_project_v1) |
project_id, project_name, project_slug, funnel_step=project_created, entrypoint |
| Project create fail | project_create_failed |
apps/core/views.py (subscription/validation), apps/api/views.py (subscription, quota, slug, queue/internal failures) |
reason, optional validation_fields, optional error_type, funnel_step=project_create_failed, entrypoint |
| Checkout start | checkout_started |
apps/core/views.py (create_checkout_session) |
plan, price_id, checkout_id, funnel_step=checkout_started, entrypoint=ui |
| Checkout success | checkout_succeeded |
apps/core/stripe_webhooks.py (handle_checkout_completed) |
checkout_id, payment_intent, amount, currency, price_id, plan, funnel_step=checkout_succeeded, entrypoint=api, stripe_event_id |
| Checkout fail | checkout_failed |
apps/pages/views.py (canceled/failed return), apps/core/views.py (Stripe setup/session exceptions), apps/core/stripe_webhooks.py (unpaid webhook) |
reason, optional error_type, plan, funnel_step=checkout_failed, entrypoint, optional stripe_event_id |
Verification checklist
- Start app with valid
POSTHOG_API_KEY+POSTHOG_HOST. - Complete one test funnel flow in local or staging:
- open landing/home (page view)
- sign up or log in
- create a project
- start checkout (and either cancel or complete with Stripe test card)
- In PostHog UI, filter recent events by your test user
distinct_idand confirm all expected event names appear. - Confirm checkout success is only emitted on Stripe webhook
checkout.session.completedwith paid status.
Local validation evidence (automated)
Run targeted tests:
pytest apps/pages/tests.py apps/core/tests/test_checkout_session.py apps/core/tests/test_projects.py apps/core/tests/test_stripe_webhooks.py apps/core/tests/test_signals.py apps/api/test_spec_001_contract.py
These tests assert event names/properties for signup, auth success/failure, project creation success/failure (UI + API), checkout start, checkout success, and checkout failure paths.
Known gaps
- API requests that fail before principal resolution (missing/invalid API key) cannot be attributed to a user
profile_id, so they are audited inProjectAPIAuditLogbut are not emitted as PostHog user events.
Verification evidence (2026-03-11)
PostHog project djass (id=339080) was validated via API by emitting test funnel events and then reading event definitions.
Observed last_seen_at values:
user_signed_up—2026-03-11T14:17:31.782029Zuser_authenticated—2026-03-11T14:17:34.027492Zproject_created—2026-03-11T14:17:31.782029Zcheckout_started—2026-03-11T14:17:32.933335Zcheckout_failed—2026-03-11T14:17:30.706677Zcheckout_succeeded—2026-03-11T14:17:34.457525Z