Files
OSGAccountServer/docs/PRODUCT_ANALYTICS.md
T
Rocky 4b465e0e5e
CI / verify (push) Has been cancelled
CI / publish (push) Has been cancelled
Add privacy-safe product analytics
Establish an idempotent analytics pipeline and internal decision dashboard while keeping event metadata allowlisted and account deletion enforceable.
2026-08-20 15:20:01 +08:00

5.2 KiB

Product analytics

OSGKeyboard analytics records product behavior metadata only. It is separate from billing, provider execution and immutable credit ledgers.

Privacy boundary

Never send or persist:

  • audio or audio-derived content;
  • keyboard input, prompts, context, transcripts or model output;
  • Apple subjects, email addresses, names, tokens, API keys or provider credentials;
  • arbitrary property names or free-form text.

The service stores a SHA-256 digest of the random installation identifier, not the identifier supplied by the client. Event DTO string representations are redacted. Product analytics rows linked to an account are deleted with that account. Anonymous installations that never link to an account are retained for 90 days and are eligible for scheduled deletion in a later operational job.

Ingestion API

POST /v1/analytics/events accepts one batch of 1 to 50 events.

  • Authentication is optional so first-open and pre-login events can be measured. Invalid bearer credentials are rejected.
  • installationId must be a client-generated UUID stored in the containing app and shared with the keyboard extension through the App Group.
  • When a valid account session is present, the installation is linked to that account. An installation cannot later be linked to a different account.
  • Every clientEventId is a client-generated UUID. The pair (installation, clientEventId) is unique.
  • Replaying an identical event is accepted and reported as replayed.
  • Reusing an event ID with different values returns 409 conflict.
  • The whole batch is validated before persistence and committed atomically.
  • occurredAt must be no more than 35 days old and no more than five minutes in the future. UTC ISO-8601 timestamps are required.

The successful response reports accepted and replayed event counts. It does not return account or installation identifiers.

Event catalog

Lifecycle events

FIRST_OPEN

  • Required: surface=APP, acquisitionChannel.
  • Optional: appVersion, osVersion.
  • Must be emitted once per installation. Server idempotency protects retries.

SESSION_STARTED

  • Required: surface (APP or KEYBOARD).
  • Optional: appVersion, osVersion.

KEYBOARD_ACTIVATED

  • Required: surface=KEYBOARD.
  • Emit when the custom keyboard becomes active, not for every keystroke.

AI events

AI_FEATURE_STARTED

  • Required: feature, executionMode, surface.
  • Optional: durationBucket is not allowed.

AI_FEATURE_SUCCEEDED

  • Required: feature, executionMode, surface, durationBucket.
  • This is the client-side core value event.
  • Managed totals remain server-authoritative; the event provides feature and surface detail.

AI_FEATURE_FAILED

  • Required: feature, executionMode, surface, failureCategory.
  • Optional: durationBucket.
  • Never include provider response bodies or user content.

Purchase events

PURCHASE_VIEWED

  • Required: surface=APP.

PURCHASE_STARTED

  • Required: surface=APP.

PURCHASE_CANCELLED

  • Required: surface=APP, failureCategory=CANCELLED.

Successful purchases are derived from verified StoreKit transactions and must not be duplicated as client success events.

Referral events

REFERRAL_SHARED

  • Required: surface=APP.

INVITE_OPENED

  • Required: surface=INVITE_WEB, acquisitionChannel=REFERRAL.
  • The app may emit this event after handling an invitation Universal Link.
  • The first-party web route separately increments a UTC daily aggregate after validating the referral code. It stores no IP address, user agent, cookie, installation ID, referral code, or other request metadata.
  • No third-party analytics script is permitted.

Referral binding, value qualification and reward are derived from server data.

Allowed dimensions

surface

  • APP
  • KEYBOARD
  • INVITE_WEB

acquisitionChannel

  • APP_STORE_ORGANIC
  • REFERRAL
  • SOCIAL_CONTENT
  • UNKNOWN

feature

  • TRANSCRIPTION
  • POLISH
  • AI_ASSISTANT
  • AGENT
  • HOTWORD
  • OTHER

executionMode

  • MANAGED
  • LOCAL
  • BYOK

failureCategory

  • NETWORK
  • PROVIDER
  • TIMEOUT
  • CANCELLED
  • INSUFFICIENT_CREDITS
  • VALIDATION
  • UNKNOWN

durationBucket

  • LT_1S
  • S1_TO_3
  • S3_TO_10
  • S10_TO_30
  • GTE_30S

appVersion and osVersion are optional ASCII release identifiers of at most 32 characters. They may not contain spaces, user-generated values or device names.

Client delivery guidance

  • Persist pending events in an append-only local queue.
  • Retry with exponential backoff after network failures and HTTP 5xx.
  • Drop events rejected with HTTP 400/422 after recording a local diagnostic counter; do not retry malformed events indefinitely.
  • Reuse the same clientEventId for every retry.
  • Send at most 50 events per batch and remove events only after a successful response.
  • Do not block the AI interaction or purchase flow on analytics delivery.

Reporting

The admin analytics endpoints combine:

  • accepted product events for acquisition, local/BYOK usage and client funnel detail;
  • settled credit usage for managed AI counts and credit consumption;
  • accounts, StoreKit and referrals for registration, monetization and referral outcomes.

Metric formulas are defined in ANALYTICS_METRICS_DICTIONARY.md.