Lexitaire / Privacy Policy / Analytics Details

What Lexitaire Actually Sends to TelemetryDeck

This page is for the minority of readers who want the exact technical detail behind the "Analytics" section of the Privacy Policy — not just "anonymous, aggregate usage," but the real event list, an actual example payload, and exactly what is and isn't in it. This page is only available in English for now, unlike the Privacy Policy itself, which is translated into every language the app supports.

Every event name Lexitaire sends

This is the complete list, taken directly from the app's own analytics code — nothing held back. The browser version sends the same event names as the native app, plus two of its own (interstitial.shown, pwa.installed) for things that only make sense in a browser, minus one native-only event (orientation.changed — the browser doesn't reliably expose rotation the same way, so it isn't sent there).

app.launch game.started game.finished gameLanguage.changed appLanguage.changed additionalGameLanguages.changed learningLanguages.changed word.checked word.applied wordCheck.opened wordLookup.opened wordsPlayed.opened myGames.opened help.opened stats.opened topScores.opened settings.opened reviewPrompt.shown reviewPrompt.writeReviewTapped reviewPrompt.rated hint.used tutorial.replayed challenge.sent challenge.accepted duel.started duel.turnSent duel.turnReceived duel.finished screenshot.taken screenshot.shareSent soundEffects.changed largeTiles.changed statusBar.changed tileStyle.changed backgroundTexture.changed backgroundImage.changed boardSize.changed timedGame.changed timerDuration.changed boardComparisonNotifications.changed orientation.changed (native only) premium.paywallShown premium.purchaseStarted premium.purchaseCompleted premium.purchaseFailed premium.trialGranted premium.upsellShown premium.upsellDismissed premium.upsellOptedOut interstitial.shown (browser only) pwa.installed (browser only)

That's it — every signal is one of these fixed names. There's no free-text or dynamically-generated event name anywhere in the code.

What travels with each one

Every signal, regardless of which event it is, carries a few things in addition to the event name:

One event is the deliberate exception to "coarse and bucketed" — word.applied sends the actual word you played and its exact score (not a bucket), specifically so board quality and average word length/score can be studied across languages. Everything else stays coarse:

Never sent, by any event: your name, an exact timestamp of when you played, or any hardware device identifier (IDFA/IDFV/UDID — Lexitaire never shows the App Tracking Transparency prompt because it never asks for one). Your IP address is never stored either — that's not Lexitaire's own code, it's TelemetryDeck's own documented policy: incoming IPs are only glanced at (the first three octets, for a country-level guess) and never written to a database or log file. The one exact value that is sent — word.applied's word and score — is deliberate and documented above, not an oversight.

Debug and Simulator builds never send anything at all, by a hard-coded guard in the code — only real App Store/TestFlight builds do.

What TelemetryDeck itself adds automatically

On top of what Lexitaire's own code sends, the TelemetryDeck SDK automatically attaches its own standard set of parameters to every signal — the same for every app that uses it, not something Lexitaire configures, and considerably more than just device/OS basics: an AppInfo block (app version/build), a Device block (model, architecture, OS version, screen size, timezone), a RunContext block (App Store vs. debug vs. TestFlight vs. simulator, locale), an SDK block (which SDK and version sent this), a UserPreference block (light/dark mode, region, language, layout direction), an Accessibility block (Reduce Motion, Bold Text, and similar system settings — whether they're on, never anything about why), a Calendar block (day of week/month/year, hour of day, whether it's the weekend — for aggregate time-of-day/day-of-week patterns, not tied to any one play), an Acquisition/Retention block (first-use date, session count, average session length), a session ID that resets each app launch, and a clientUser value: an opaque, per-install identifier TelemetryDeck generates to let a dashboard count roughly how many distinct people are using a feature, without it being your Apple ID, device serial number, or IDFA. Lexitaire's code never sets or overrides clientUser with anything of its own. The SDK also attaches around 19 deprecated flat-named duplicates of several of the fields above (e.g. a bare platform/isDebug/locale/region, alongside their namespaced TelemetryDeck.* equivalents) — kept only for older dashboards that predate the namespaced names, and omitted from the example below since they're byte-identical to fields already shown. For the complete, authoritative list, see TelemetryDeck's own documentation.

A real example (native app)

Here's an actual word.applied signal from iPhone/iPad/Apple TV, exactly as TelemetryDeck receives it (ID values shown are randomly generated per-install/per-session, not tied to any account) — every field the SDK attaches, not a trimmed-down excerpt. The outer [ ] is real too: the SDK batches whatever signals are queued into one array per HTTP request rather than sending each separately — this example just has one signal in it:

[{
    "appID": "EAF44E29-4BA0-44C8-8FB4-8FADF5639DEC",
    "clientUser": "0ecefd2c-3d40-4bac-863a-09d3e4988467",
    "sessionID": "14381279-9ee4-4880-a255-73268e4b5449",
    "type": "word.applied",
    "payload": {
        "TelemetryDeck.AppInfo.buildNumber": "8",
        "TelemetryDeck.AppInfo.version": "4.1.0",
        "TelemetryDeck.AppInfo.versionAndBuildNumber": "4.1.0 (build 8)",
        "TelemetryDeck.Device.architecture": "arm64",
        "TelemetryDeck.Device.modelName": "iPhone16,2",
        "TelemetryDeck.Device.operatingSystem": "iOS",
        "TelemetryDeck.Device.orientation": "Portrait",
        "TelemetryDeck.Device.platform": "iOS",
        "TelemetryDeck.Device.screenResolutionWidth": "430.0",
        "TelemetryDeck.Device.screenResolutionHeight": "932.0",
        "TelemetryDeck.Device.screenScaleFactor": "3.0",
        "TelemetryDeck.Device.systemVersion": "iOS 17.5.0",
        "TelemetryDeck.Device.systemMajorVersion": "iOS 17",
        "TelemetryDeck.Device.systemMajorMinorVersion": "iOS 17.5",
        "TelemetryDeck.Device.timeZone": "UTC-7",
        "TelemetryDeck.RunContext.isAppStore": "true",
        "TelemetryDeck.RunContext.isDebug": "false",
        "TelemetryDeck.RunContext.isSimulator": "false",
        "TelemetryDeck.RunContext.isTestFlight": "false",
        "TelemetryDeck.RunContext.language": "en",
        "TelemetryDeck.RunContext.locale": "en_US",
        "TelemetryDeck.RunContext.targetEnvironment": "native",
        "TelemetryDeck.SDK.name": "SwiftSDK",
        "TelemetryDeck.SDK.nameAndVersion": "SwiftSDK 2.14.2",
        "TelemetryDeck.SDK.version": "2.14.2",
        "TelemetryDeck.UserPreference.colorScheme": "Light",
        "TelemetryDeck.UserPreference.language": "en",
        "TelemetryDeck.UserPreference.layoutDirection": "leftToRight",
        "TelemetryDeck.UserPreference.region": "US",
        "TelemetryDeck.Accessibility.isReduceMotionEnabled": "false",
        "TelemetryDeck.Accessibility.isBoldTextEnabled": "false",
        "TelemetryDeck.Accessibility.isInvertColorsEnabled": "false",
        "TelemetryDeck.Accessibility.isDarkerSystemColorsEnabled": "false",
        "TelemetryDeck.Accessibility.isReduceTransparencyEnabled": "false",
        "TelemetryDeck.Accessibility.shouldDifferentiateWithoutColor": "false",
        "TelemetryDeck.Accessibility.preferredContentSizeCategory": "L",
        "TelemetryDeck.Calendar.dayOfMonth": "20",
        "TelemetryDeck.Calendar.dayOfWeek": "4",
        "TelemetryDeck.Calendar.dayOfYear": "232",
        "TelemetryDeck.Calendar.weekOfYear": "34",
        "TelemetryDeck.Calendar.isWeekend": "false",
        "TelemetryDeck.Calendar.monthOfYear": "8",
        "TelemetryDeck.Calendar.quarterOfYear": "3",
        "TelemetryDeck.Calendar.hourOfDay": "15",
        "TelemetryDeck.Acquisition.firstSessionDate": "2026-07-15",
        "TelemetryDeck.Retention.averageSessionSeconds": "245",
        "TelemetryDeck.Retention.distinctDaysUsed": "12",
        "TelemetryDeck.Retention.distinctDaysUsedLastMonth": "9",
        "TelemetryDeck.Retention.totalSessionsCount": "34",
        "TelemetryDeck.Retention.previousSessionSeconds": "198",
        "adsEnabled": "true",
        "gameLanguages": "English",
        "deviceModel": "iPhone 16",
        "isPremium": "false",
        "deviceLanguageCount": "2+",
        "multilingualPlayer": "false",
        "word": "CAT",
        "score": "15"
    }
}]

Built directly from the exact TelemetryDeck Swift SDK version this app ships (2.14.2's DefaultSignalPayload.parameters) rather than a one-off network capture, since Debug/Simulator builds never send a real signal at all (see below) — reading the SDK's own source is the only way to see a build's complete, real field list at all.

A real example (browser)

The browser version posts to a separate TelemetryDeck app from native's (so usage stays cleanly separable in the dashboard), and the SDK's default parameters reflect the browser/OS instead — plus a few browser-only fields (browserName, browserVersion, userAgent) native never sends.

This one isn't reconstructed from source — it's a literal screenshot of Chrome's own DevTools Network panel, captured by Marc Abramowitz (this site's author) playing Lexitaire in his own browser, in San Jose, California, USA, on August 20, 2026, having just played the word EXTRADITIONS for 240 points:

Chrome DevTools Network panel showing the raw request payload for a word.applied signal, including the word EXTRADITIONS and score 240

Transcribed as text, for anyone who'd rather copy/search it than read a screenshot:

[{
    "appID": "EAF44E29-4BA0-44C8-8FB4-8FADF5639DEC",
    "clientUser": "0ecefd2c-3d40-4bac-863a-09d3e4988467",
    "sessionID": "dcd1ac63-1666-47b9-866f-ed8dc28645e8",
    "type": "word.applied",
    "payload": {
        "TelemetryDeck.RunContext.language": "en",
        "TelemetryDeck.RunContext.locale": "en-US",
        "TelemetryDeck.UserPreference.language": "en",
        "TelemetryDeck.UserPreference.colorScheme": "Light",
        "TelemetryDeck.UserPreference.layoutDirection": "leftToRight",
        "TelemetryDeck.UserPreference.region": "US",
        "TelemetryDeck.Device.timeZone": "America/Los_Angeles",
        "TelemetryDeck.Device.screenResolutionWidth": "1920",
        "TelemetryDeck.Device.screenResolutionHeight": "1080",
        "TelemetryDeck.Device.screenScaleFactor": "2",
        "TelemetryDeck.Device.operatingSystem": "macOS",
        "TelemetryDeck.Device.systemVersion": "10.15.7",
        "TelemetryDeck.Device.platform": "desktop",
        "TelemetryDeck.Device.brand": "Apple",
        "browserName": "Chrome",
        "browserVersion": "151.0.0.0",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36",
        "word": "EXTRADITIONS",
        "score": "240"
    }
}]

Look at everything that's genuinely absent: no name ("Marc"), no IP address, no street address or city ("San Jose"), no device serial number, no advertising ID. The only location-shaped fields at all are region ("US") and timeZone ("America/Los_Angeles" — the whole Pacific time zone) — both broad enough to be shared by tens of millions of people, nowhere near enough to place anyone in a specific city. clientUser stayed the same as an earlier capture on this page taken from the same browser profile — expected, since it's a stable per-install identifier, not a coincidence or a leak. sessionID, on the other hand, is different every time, since it resets on every page load.

Curious enough to check this yourself? Here's exactly how this screenshot was captured — no special tools needed, just your browser's own DevTools.

Note what's missing in both examples above: no name, no raw timestamp of the play itself (TelemetryDeck stamps its own receipt time server-side, not something the app sends). The word and score themselves are present here, on purpose — see above.

Turn this off anytime on iPhone, iPad, or Apple TV: Settings → "Share Anonymous Analytics". See the Privacy Policy for the full, plain-language version of all of this.