Skip to main content
Second captures lightweight product analytics after onboarding. Analytics are enabled by default, and the default user setting is anonymized. The PostHog project token is a public client/project token, not a private API key. Configure it with SECOND_POSTHOG_TOKEN when overriding the built-in release default, and use SECOND_POSTHOG_HOST for non-US PostHog projects.

Capture path

Browser code does not send directly to PostHog. It posts events to Second’s same-origin /api/analytics/capture endpoint. The web route:
  • requires an authenticated, onboarded user
  • allowlists the supported event names
  • sanitizes property keys and values
  • applies the current anonymization mode
  • forwards the final payload to PostHog
This keeps the privacy and tenant checks in Second instead of trusting every call site to send the right PostHog payload.

Events

Second currently captures:
  • page viewed
  • onboarding finished
  • chat initiated
  • sidebar clicked
  • import existing app clicked
  • import existing app triggered
  • build completed
  • build failed
  • approval shown
  • approval acted
  • integration setup started
  • integration setup completed
  • app displayed
  • app agent triggered
  • app agent finished
  • app agent error
  • showed suggestions tool called
  • suggestion picked
  • agents approved
All browser analytics events include anonymous-safe page context:
  • surface, such as workspace_home, app_chat, settings, library, or workspace_agents
  • route_shape, such as /w/:workspace/apps/:objectId
  • small client context such as viewport size
The route shape removes workspace IDs, app IDs, run IDs, UUIDs, and integration route segments before the event is sent. Build and agent events use counts and outcomes where possible: message count, tool call count, attachment count, file count, duration, runtime ID/model, and failure phase/error code. Raw prompts, messages, app names, agent names, URLs, and IDs are still stripped in anonymized mode. The analytics endpoint also adds release metadata server-side to every event:
  • release_version
  • release_package
  • release_runtime
  • cli_launcher_version
  • cli_launcher_package
For CLI runs these values come from the launcher/runtime environment. In other deployment modes they may be null unless the deployment sets release environment variables.

Anonymized mode

When anonymization is on, the browser creates one stable local anonymous ID in localStorage:
second:analytics-anonymous-id:v1
The value is an anon_... UUID generated by Second. It is sent as the PostHog distinct_id for anonymized events, so repeated events from the same browser are grouped together without identifying the user. Anonymized events deliberately:
  • do not call PostHog $identify
  • do not alias the anonymous ID to the real user ID
  • set $process_person_profile: false
  • strip user, workspace, app, run, agent, prompt, message, raw error, suggestion, URL, and referrer identifiers
  • strip generic identifier-shaped properties such as *_id, *_ids, *_email, *_name, and *_names
This means anonymized events stay useful for aggregate product analytics while remaining separate from the user’s PostHog person profile.

Non-anonymized mode

Users can turn off anonymization from the workspace account menu under Usage data settings. When anonymization is off, Second sends a PostHog $identify event for the onboarded user and uses the Second user ID as the PostHog distinct_id. Non-anonymized events may include the user, workspace, app, agent, message, and screen properties needed for debugging and product analysis.

Screen recording

Screen recording is a separate opt-in inside Usage data settings. It is off by default, and enabling it also turns anonymization off because replay captures the actual Second interface for product debugging. Regular product analytics still use the same-origin /api/analytics/capture route. Screen recording is the exception: PostHog session replay runs in the browser through posthog-js, because replay is captured from the browser DOM and cannot be produced by the server-side capture endpoint. When screen recording is enabled, the browser loads the public PostHog project token and host from Second’s authenticated analytics config route, identifies the current onboarded user, and starts PostHog session recording. The SDK is configured without PostHog pageview/autocapture product events so it does not replace or duplicate Second’s sanitized analytics capture path. When screen recording is disabled, anonymization is re-enabled, telemetry is disabled, or the user signs out, Second stops PostHog session recording and resets the browser SDK state on that tab. Browser-level password-field masking from PostHog/rrweb still applies, but Second does not apply its anonymized analytics redaction model to replay after the user explicitly enables recording.

Switching modes

Switching from anonymized to non-anonymized affects future events only. Second does not merge or alias the local anonymous ID into the identified PostHog person. That is intentional: PostHog’s standard frontend SDK can link anonymous history to a user after identify, but doing that here would make the anonymized setting weaker. In Second, historical anonymized events remain anonymous even if the same user later disables anonymization. On sign-out, Second resets the local anonymous ID. This prevents two different users sharing one browser profile from being grouped under the same anonymous PostHog identity.

Disabling analytics

For local development, disable analytics for a run with:
npm run dev -- --disable-telemetry
npm run dev -- --no-analytics
SECOND_POSTHOG_DISABLED=1 npm run dev
For CLI runs:
npx --yes @second-inc/cli --disable-telemetry
For deployments, set either of:
SECOND_POSTHOG_DISABLED=1
SECOND_TELEMETRY_DISABLED=1