PostHog Funnel Analytics
Goal
Track core funnel behavior reliably in PostHog:
- page view
- signup/auth
- project create
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)POSTHOG_ENABLED— must be enabled for capture; a valid project key alone is not sufficient
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 |
Explicit navigation capture in frontend/src/js/analytics.js, loaded through the shared template component; SDK capture_pageview: false |
sanitized $current_url and $pathname, plus bounded capture metadata |
| 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), funnel_step=auth_failed, entrypoint |
| Project create | project_created |
apps/core/views.py (create_project), apps/api/views.py (create_project_v1) |
project_id, funnel_step=project_created, entrypoint |
| Project create fail | project_create_failed |
apps/core/views.py (validation), apps/api/views.py (quota, slug, queue/internal failures) |
reason, optional validation_fields, optional error_type, funnel_step=project_create_failed, entrypoint |
Browser page views run once on initialization and when the normalized path
changes through supported HTMX history events or popstate. Query strings and
fragments are removed from captured URLs; account paths and selected private
identifiers are normalized. This is not a claim that every path is public-safe.
Server properties pass through the allowlist in djass/analytics.py before
capture. In particular, project_name, project_slug, and required_scope are
not sent by that boundary even when a producer supplies them. The table describes
the retained properties, not every argument passed to a tracking task.
Source rechecked September 27, 2026. This mapping does not establish production delivery, consent compliance, or an attributed conversion rate.
Verification checklist
- Start app with
POSTHOG_ENABLEDenabled and validPOSTHOG_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
- In PostHog UI, filter recent events by your test user
distinct_idand confirm all expected event names appear.
Local validation evidence (automated)
Run targeted tests:
pytest apps/pages/tests.py apps/core/tests/test_projects.py apps/core/tests/test_signals.py \
apps/api/test_project_endpoints.py apps/api/test_api_key_authorization.py
These tests assert event names/properties for signup, auth success/failure, and project creation success/failure (UI + API).
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.782029Z