Skip to content

PostHog Events Reference

All custom PostHog events tracked in the app. Each event uses the trackEvent() helper from services/analyticsService.ts.

Naming convention: category:object_action (lowercase, snake_case, present-tense verbs).


Onboarding Events

onboarding:flow_start

Purpose Fired when a user lands on the intro screen. Top of the funnel — use to measure total visitors entering the flow.
Properties is_invited: boolean — whether the user has an invite token
Files components/onboarding/screens.tsx (ProfileIntro mount/render)

onboarding:step_view

Purpose Fired when a user navigates to any step. Use to build the step-by-step funnel and identify drop-off points.
Properties step_name: 'social_links' / 'creator_type' / 'effort_level' / 'creator_stage' / 'what_youd_make' / 'review' / 'name_email' / 'confirmation', step_number: 1–8, is_invited: boolean
Files context/onboardingContext.tsx (inside goTo)

onboarding:step_complete

Purpose Fired when a user completes a step (clicks Continue). Paired with step_view to measure per-step completion rate.
Properties step_name, step_number, is_invited (same as step_view), plus step-specific properties below
Step-specific social_links: link_count, platform_count, platforms (array), link_types (array of 'profile'/'other'). creator_type / effort_level / creator_stage: selected_value (the card option chosen). what_youd_make: char_count.
Files components/onboarding/stepScreens.tsx
Purpose Fired when a user validates a social link (on blur). Measures engagement depth and platform distribution.
Properties platform: detected platform string (e.g. 'YOUTUBE', 'TIKTOK', 'INSTAGRAM'), link_type: 'profile' / 'other'
Files components/onboarding/stepScreens.tsx (SocialLinksScreen — on blur when platform detected)
Purpose Fired when a user removes a social link. Measures friction or correction behavior.
Properties none
Files components/onboarding/stepScreens.tsx (SocialLinksScreen — remove button click)

onboarding:form_submit

Purpose Fired when a user initiates form submission (before the API responds). Measures submit attempt volume — compare against success/fail to understand error rates.
Properties is_invited: boolean
Files components/onboarding/screens.tsx (ReviewScreen handleInviteSubmit, NameEmailScreen handleSubmit)

onboarding:submit_success

Purpose Primary growth event. Fired after a successful application submission. Use for activation funnels, conversion rate, and cohort analysis.
Properties is_invited: boolean, link_count: number of valid links submitted, platform_count: number of unique platforms, platforms: array of platform strings, link_types: array of 'profile'/'other'
Person properties set signup_date: ISO 8601 timestamp (via setPersonPropertiesOnce)
Files components/onboarding/screens.tsx (ReviewScreen after submitInvited success, NameEmailScreen after submit success)

onboarding:submit_fail

Purpose Fired when a submission fails. Use error_code to identify common failure reasons (e.g. already_verified, expired_token, network errors).
Properties is_invited: boolean, error_code: the error code string (e.g. 'already_verified', 'already_applied', 'expired_token', 'network_error')
Files components/onboarding/screens.tsx (ReviewScreen catch block, NameEmailScreen catch block)

onboarding:experiment_variant_assigned

Purpose Fired once per session when the PostHog feature flag Landing-page-vs-Step-1 resolves. Records which experiment arm this user is in so downstream funnel analysis can be segmented by variant.
Properties experiment: 'Landing-page-vs-Step-1', variant: 'skip_intro' | 'control'
Super property registered experiment_landing_vs_step1 ('skip_intro' or 'control') — attached to every subsequent event in the session.
Person property set (once) experiment_landing_vs_step1 — stored on the PostHog person profile for cohort analysis.
Files context/onboardingContext.tsx

Super property: land_path

Purpose Registered via posthog.register() on first load when the app is opened with a ?lp=<path> param, so every subsequent event carries the in-profile destination the visitor was sent to apply for. Use it to segment the funnel by entry point (e.g. a specific quest). Only same-origin relative paths are accepted — anything absolute or protocol-relative is dropped and no super property is set.
Files shared/sharedHelpers.ts (sanitizeLandPath), components/onboarding/onboarding.tsx (InviteChecker — before the invite-token guard, so it also applies to self-serve visitors)

Invite Events

invite:token_check

Purpose Fired when the app begins checking an invite token. Top of the invite funnel.
Properties none
Files components/onboarding/onboarding.tsx (InviteChecker — before API call)

invite:token_valid

Purpose Fired when an invite token is validated successfully. Signals a real invited user has entered the flow. Also triggers posthog.identify() with the user's email.
Properties none
Files components/onboarding/onboarding.tsx (InviteChecker — after successful check response)

invite:token_invalid

Purpose Fired when an invite token is rejected. Use reason to understand why (expired, already used, malformed).
Properties reason: the rejection reason string (e.g. 'expired_token', 'invalid_token', 'already_verified', 'already_applied')
Files components/onboarding/onboarding.tsx (InviteChecker — when res.valid === false or res.flagged === true)

invite:variant_assigned

Purpose Fired once per valid invite when the user is attributed to a subject-line A/B variant. Also registers the subject_line_key super property so every subsequent funnel event carries the variant (enabling conversion-by-variant analysis).
Properties subject_line_key: the resolved subject-line variant key (e.g. 'default', 'curiosity'). Returned by /api/invite/check.
Files components/onboarding/onboarding.tsx (InviteChecker — after invite:token_valid when res.subjectLineKey is present)

Super property: subject_line_key

Purpose Registered via posthog.register() so it rides along on all events after invite assignment. The variant is chosen by the caller of the bulk-invite API (invites[].subjectLineKey), stored on the invite doc, and also attached to the Resend email as a subject_line_key tag for open/click-rate analysis.
Files services/analyticsService.ts (registerSuperProperties), components/onboarding/onboarding.tsx

Verify Events

verify:page_load

Purpose Fired when the /verify page loads. Top of the email verification funnel.
Properties none
Files app/verify/page.tsx (on mount)

verify:success

Purpose Fired when email verification succeeds. Confirms the user completed the full flow (apply → check email → verify).
Properties none
Files app/verify/page.tsx (after successful verification API response)

verify:fail

Purpose Fired when email verification fails. Use error_code to identify issues (expired links, already verified, invalid tokens).
Properties error_code: the error code string
Files app/verify/page.tsx (catch block / error response)

verify:variant_assigned

Purpose Fired once per verification reminder when the user is attributed to a subject-line A/B variant. Also registers the verify_subject_line_key super property so every subsequent funnel event carries the variant (enabling conversion-by-variant analysis).
Properties verify_subject_line_key: the subject-line variant key (e.g. 'rem48h_access_expiring', 'rem48h_last_step'). Passed via URL parameter ?vsl=<key>.
Files app/verify/page.tsx (on mount when vsl query parameter is present)

Super property: verify_subject_line_key

Purpose Registered via posthog.register() so it rides along on all events after verification page load. The variant is randomly assigned by the reminder lambda, included in the verification URL as a vsl parameter, and also attached to the Resend email as a subject_line_key tag for open/click-rate analysis.
Files services/analyticsService.ts (registerSuperProperties), app/verify/page.tsx

Dashboard Metrics (from Linear PEA-1800)

Metric How to compute in PostHog
Avg # of platforms per user submit_success → avg of platform_count property
% answers for closed questions step_complete where step_name = creator_type/effort_level/creator_stage → breakdown by selected_value
Links to profiles vs other submit_success → breakdown of link_types array, or link_add → breakdown by link_type
Most shared platforms link_add → breakdown by platform, or submit_success → breakdown of platforms array

Event → Page/Step Map (Quick Reference)

Page / Step Events fired
Intro screen (intro) onboarding:flow_start
Step 1 — Social Links (step1) onboarding:step_view, onboarding:link_add, onboarding:link_remove, onboarding:step_complete
Step 2 — Creator Type (step2) onboarding:step_view, onboarding:step_complete
Step 3 — Effort Level (step3) onboarding:step_view, onboarding:step_complete
Step 4 — Creator Stage (step4) onboarding:step_view, onboarding:step_complete
Step 5 — What You'd Make (step5) onboarding:step_view, onboarding:step_complete
Review (review) onboarding:step_view, onboarding:form_submit, onboarding:submit_success, onboarding:submit_fail
Name & Email (name-email) onboarding:step_view, onboarding:form_submit, onboarding:submit_success, onboarding:submit_fail
Confirmation (confirmation) onboarding:step_view
Invite check (InviteChecker) invite:token_check, invite:token_valid, invite:token_invalid
Verify page (/verify) verify:page_load, verify:variant_assigned, verify:success, verify:fail

Key Funnels

Application Completion Funnel

onboarding:flow_start
  → onboarding:step_view (step 1)
    → onboarding:step_complete (step 1)
      → ... (steps 2-5) ...
        → onboarding:step_view (review)
          → onboarding:form_submit
            → onboarding:submit_success

Email Verification Funnel

onboarding:submit_success
  → verify:page_load
    → verify:variant_assigned (if from reminder email with vsl parameter)
      → verify:success

Invite Funnel

invite:token_check
  → invite:token_valid
    → onboarding:step_view (step 1)
      → ... (steps 2-5) ...
        → onboarding:form_submit
          → onboarding:submit_success

The classifyLinkType() helper in shared/sharedHelpers.ts categorizes links:

Type Logic Examples
profile Known platform (matches PLATFORM_PATTERNS) youtube.com/@channel, instagram.com/user, tiktok.com/@user
other Unrecognized platform myportfolio.com, linktree.com/user, custom domains