IHNYC RC Calendar Mixpanel Tracking

Mixpanel is used for privacy-preserving analytics across the Programs calendar flow. The server hashes emails with a pepper before sending distinct_id values.

Privacy model

  • distinct_id is derived from sha256(TOKEN_PEPPER:email).
  • Raw emails are never sent to Mixpanel.
  • If TOKEN_PEPPER is missing, the hash uses a nopepper: prefix.

Server-side event sources

Magic link request (POST /api/subs/new?calendar_id=programs)

Emits:

  • programs_magiclink_request_started
  • programs_magiclink_turnstile_failed
  • programs_magiclink_turnstile_passed
  • programs_magiclink_subscriber_disabled
  • programs_magiclink_request_rate_limited
  • programs_magiclink_verify_request_created
  • programs_magiclink_email_sent
  • programs_magiclink_email_send_failed

Key props include distinct_id, calendar_id, and error or retry metadata.

  • programs_magiclink_request_started: Initial submit passed validation.
  • programs_magiclink_turnstile_failed: Turnstile verification failed.
  • programs_magiclink_turnstile_passed: Turnstile verification succeeded.
  • programs_magiclink_subscriber_disabled: Email exists but subscriber is disabled.
  • programs_magiclink_request_rate_limited: Cooldown enforced (60s).
  • programs_magiclink_verify_request_created: Verify request persisted.
  • programs_magiclink_email_sent: Resend accepted the email request.
  • programs_magiclink_email_send_failed: Resend failed to send.

Emits:

  • programs_calendar_disabled
  • programs_magiclink_missing_v
  • programs_magiclink_invalid_or_expired
  • programs_magiclink_clicked
  • programs_magiclink_consumed
  • programs_email_disabled_at_verify
  • programs_token_minted
  • programs_token_mint_failed
  • programs_subscribe_redirected
  • programs_calendar_disabled: Calendar disabled in DB.
  • programs_magiclink_missing_v: Link missing v param.
  • programs_magiclink_invalid_or_expired: No matching, unconsumed verify request.
  • programs_magiclink_clicked: Valid link clicked before consume.
  • programs_magiclink_consumed: Verify request consumed.
  • programs_email_disabled_at_verify: Subscriber disabled at verify time.
  • programs_token_minted: Token minted successfully.
  • programs_token_mint_failed: Token mint failed after retries.
  • programs_subscribe_redirected: Non-JSON clients redirected to subscribe page.

ICS delivery (GET /cal/programs.ics)

Emits:

  • programs_token_invalid (missing, not found, calendar disabled, subscriber disabled)
  • programs_token_revoked
  • programs_token_expired
  • programs_token_seen (daily bucket)
  • programs_ics_fetched (200 or 304)

ICS delivery meanings

  • programs_token_invalid: Missing or invalid token, calendar disabled, or subscriber disabled.
  • programs_token_revoked: Token revoked.
  • programs_token_expired: Token expired.
  • programs_token_seen: Token observed (daily bucket).
  • programs_ics_fetched: ICS served or 304 cache hit.

Client-side event sources

Subscribe programs page (public/subscribe-programs.js)

When Mixpanel is present in the browser, these events are recorded:

  • programs_add_to_apple_clicked
  • programs_add_to_google_clicked
  • programs_add_to_outlook_clicked
  • programs_download_ics_clicked

Each includes calendar_id, page, and the outbound link URL.

Admin diagnostics

Mixpanel test endpoint

  • GET /api/admin/mixpanel-test sends a single mixpanel_connection_test event.
  • Admin UI (/admin) exposes a “Test Mixpanel” button that calls the endpoint.

Diagrams

sequenceDiagram
  participant User
  participant UI as Subscribe Page
  participant API as Pages Functions
  participant MP as Mixpanel
  participant Resend

  User->>UI: Submit name + email
  UI->>API: POST /api/subs/new
  API->>MP: programs_magiclink_request_started
  API->>MP: programs_magiclink_turnstile_passed or failed
  API->>Resend: Send magic link
  API->>MP: programs_magiclink_email_sent or failed

  User->>UI: Open magic link
  UI->>API: GET /api/subs/verify
  API->>MP: programs_magiclink_clicked
  API->>MP: programs_magiclink_consumed
  API->>MP: programs_token_minted or mint_failed

ICS fetch tracking

flowchart LR
  Client[Calendar Client] -->|GET /cal/programs.ics| API[Pages Functions]
  API -->|Validate token| DB[D1]
  API -->|Fetch programs.ics| R2[R2 CAL_BUCKET]
  API -->|Track events| MP[Mixpanel]

Configuration

  • MIXPANEL_PROJECT_TOKEN required for tracking.
  • MIXPANEL_API_HOST defaults to https://api-eu.mixpanel.com when unset.
  • MIXPANEL_ENV tags events by environment.

Troubleshooting

  • No events: confirm MIXPANEL_PROJECT_TOKEN is set and non-empty.
  • Wrong region: set MIXPANEL_API_HOST to the correct Mixpanel region (EU vs US).
  • Admin test failing: call GET /api/admin/mixpanel-test and inspect response body.
  • Client events missing: ensure Mixpanel is loaded on /subscribe-programs and no ad blockers are stripping the script.
  • Distinct IDs look wrong: verify TOKEN_PEPPER is set consistently across environments.