Documentation
Analytics

Breakdown your app's AI usage

These advanced analytic features are available on the Pro plan.

What's captured on each request

The SDK adds these headers to every authenticated request. Gate/AI records them and strips them before forwarding to the provider.

Field Header Source Notes
Locale X-Client-Locale Automatic Language and region, e.g. en-US.
App version X-App-Version Automatic From the app bundle / build config.
OS X-OS-Version Automatic e.g. 18.6 or Android 15.
Type X-Device-Type Automatic iPhone, iPad, Android.
Device model X-Device-Model Automatic Hardware identifier, e.g. iPhone16,1.
Environment X-Environment Automatic development, testflight, or production.
SDK version X-SDK-Version Automatic Which Gate/AI SDK release made the request.
Identifier X-Device-Identifier Automatic on iOS; opt-in on Android Vendor identifier (iOS) or ANDROID_ID (Android, deviceIdentifierEnabled). Falls back to IP when absent.
Country Network edge Derived server-side from the request; no location permission involved.
Status (user) X-User-Status You Free-form segment for analytics, e.g. trial, premium.
User identifier X-User-Identifier You Opaque account ID from your system — never an email or name.
Feature X-App-Feature You Which in-app feature made the call, for per-feature cost.
Tier X-User-Tier You Plan tier; required to enable per-tier usage limits.

The four fields you set

Everything else is automatic. Set these on the client once (they can change at any time, e.g. after a purchase) and they ride along on every request.

Swift

gateAIClient.userIdentifier = account.analyticsId  // opaque ID
gateAIClient.userTier       = "pro"                // limits key
gateAIClient.userStatus     = "trial"              // free-form segment
gateAIClient.appFeature     = "chat"               // per-feature cost

Kotlin

gateAIClient.userIdentifier = account.analyticsId  // opaque ID
gateAIClient.userTier       = "pro"                // limits key
gateAIClient.userStatus     = "trial"              // free-form segment
gateAIClient.appFeature     = "chat"               // per-feature cost

Tier vs. status. They look similar but do different jobs. userTier is an enforcement key — per-tier usage limits match it exactly, case-sensitively. userStatus is only ever a label for breaking down analytics. Keep tier names stable and short (free, pro, team) and put anything experimental or descriptive in status — trial, churn-risk, beta-cohort, onboarding-day-1, or a lifecycle stage like active / lapsed.

Privacy. Use an opaque identifier for userIdentifier — a UUID or hash from your own system, not an email address or name. On Android the persistent device identifier is off by default because it carries a data-collection disclosure obligation; enable it with deviceIdentifierEnabled only if you've covered it in your privacy disclosure.

How token cost is calculated

Cost is derived, not reported by the provider. Shortly after a request completes, Gate/AI prices it from available public pricing. Spend shows on the gate page and in the Analytics tab as a daily series like this:

A request is priced from its input and output token counts. When the provider only reports a total, an assumed input/output split is applied and the cost is marked "(estimated)" in the request detail; requests with no token data, or a model that isn't priced yet, show a dash and are excluded from totals.

Consider cost figures as estimates for budgeting. Because of advanced model features like caching and varying context size, they cannot be exact.