> ## Documentation Index
> Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Dictionary

> Complete reference of data collected and event schemas across the Web SDK, Unity SDK, and REST API

> [!WARNING]
>
> The Web SDK, Unity SDK, and REST API are currently in **alpha**. The data collected and event schemas may change between releases.

Full reference of data collected and event schemas for the [Web SDK](https://docs.immutable.com/docs/products/audience/analytics/web-sdk.md), [Unity SDK](https://docs.immutable.com/docs/products/audience/analytics/unity-sdk.md), and [REST API](https://docs.immutable.com/docs/products/audience/analytics/rest-api.md), and the data forwarded externally by [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md). Use it to understand what each integration sends, when it sends it, and what properties each event carries. Also useful for privacy reviews, legal assessments, and technical audits.

## Cookies

First-party cookies only. No third-party cookies are created.

The Unity SDK does not use cookies. It persists `AnonymousId` and queued events to native local storage instead.

> [accordion] imtbl\_anon\_id Web SDK
>
> Persistent anonymous device identifier (UUID v4).
>
> | Property | Value |
> | - | - |
> | Lifetime | 2 years |
> | Scope | First-party, current hostname |
> | Attributes | `SameSite=Lax`, `Secure` on HTTPS |

> [accordion] \_imtbl\_sid Web SDK
>
> Session continuity across page loads. Refreshed on each tracking call. Expires after 30 minutes of inactivity.
>
> | Property | Value |
> | - | - |
> | Lifetime | 30 minutes (rolling) |
> | Scope | First-party, current hostname |
> | Attributes | `SameSite=Lax`, `Secure` on HTTPS |

> [accordion] \_ga Web SDK
>
> Google Analytics client ID. Read-only. The Web SDK reads this cookie for cross-platform identity stitching but does not write it.
>
> | Property | Value |
> | - | - |
> | Source | Google Analytics |

> [accordion] \_fbc Web SDK
>
> Facebook click ID. Read-only. The Web SDK reads this cookie for cross-platform identity stitching but does not write it.
>
> | Property | Value |
> | - | - |
> | Source | Meta (Facebook) |

> [accordion] \_fbp Web SDK
>
> Facebook browser ID. Read-only. The Web SDK reads this cookie for cross-platform identity stitching but does not write it.
>
> | Property | Value |
> | - | - |
> | Source | Meta (Facebook) |

## Auto-Tracked

Signals collected and events fired by the integration without any studio code.

### Device Fingerprint Signals

These signals are collected automatically when consent is `anonymous` or `full`.

> [tab] Web SDK
>
> | Signal | Source | Example |
> | - | - | - |
> | User agent | `navigator.userAgent` | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...` |
> | Screen resolution | `screen.width` × `screen.height` | `1920×1080` |
> | Timezone | `Intl.DateTimeFormat().resolvedOptions().timeZone` | `America/New_York` |
> | Browser language | `navigator.language` | `en-US` |
> | IP address | Server-side from request headers | Raw IP stored for geo enrichment |

> [tab] Unity SDK
>
> The Unity SDK collects a different fingerprint set (CPU, GPU, RAM, OS family, Unity version, screen DPI, device model) and emits it once per session as part of [`game_launch`](#auto-tracked-events) rather than on every event.

### Attribution Signals

The Web SDK collects these URL-based signals. Mobile Unity builds with attribution enabled collect a separate set of device-level signals. Desktop Unity builds collect none.

> [tab] Web SDK
>
> The Web SDK attaches them to the first `page()` call and the `sign_up` and `link_clicked` events.
>
> | Signal | Source | Example |
> | - | - | - |
> | UTM parameters | URL query string | `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content` |
> | Google click ID | URL query string | `gclid` |
> | Meta click ID | URL query string | `fbclid` |
> | TikTok click ID | URL query string | `ttclid` |
> | Reddit click ID | URL query string | `rdt_cid` |
> | Microsoft click ID | URL query string | `msclkid` |
> | Display & Video 360 click ID | URL query string | `dclid` |
> | LinkedIn click ID | URL query string | `li_fat_id` |
> | X click ID | URL query string | `twclid` |
> | Referrer | `document.referrer` | The referring page URL |
> | Landing page | `window.location.href` (first page in session) | Entry point URL |
> | Referral code | URL query string | `referral_code`: a custom parameter you add to campaign links (e.g. `?referral_code=influencer-abc`) to track referral sources |

> [tab] Unity SDK
>
> Desktop builds do not collect URL-based attribution signals. The closest analogue is the studio-supplied `distribution_platform` property on [`game_launch`](#auto-tracked-events).
>
> Mobile [attribution builds](https://docs.immutable.com/docs/products/audience/analytics/unity-sdk.md#mobile) (`AUDIENCE_MOBILE_ATTRIBUTION` + `EnableMobileAttribution = true`) ship additional signals with `game_launch`.
>
> **iOS**
>
> | Property | Type | Consent | Description |
> | - | - | - | - |
> | `att_status` | `string` | `Anonymous`+ | ATT authorization status: `notDetermined`, `restricted`, `denied`, or `authorized`. |
> | `idfa` | `string` | `Full` | Advertising identifier. Present only when ATT status is `authorized` and consent is `Full`. |
> | `skan_registered` | `boolean` | `Anonymous`+ | `true` on the launch where SKAdNetwork first-install registration fires. Omitted on subsequent launches. |
>
> **Android**
>
> | Property | Type | Consent | Description |
> | - | - | - | - |
> | `gaid` | `string` | `Full` | Google Advertising ID. Omitted when `gaid_limit_ad_tracking` is `true`. Available from the second launch onwards. |
> | `gaid_limit_ad_tracking` | `boolean` | `Anonymous`+ | Whether the user has opted out of ad personalization. Available from the second launch onwards. |

### Auto-Tracked Events

Events fired by the integration without studio code. Title badges indicate which integrations emit each event. Trigger conditions and per-integration property differences are described inside the accordion.

> [accordion] game\_launch Unity SDK
>
> Player launched the game. The Unity SDK fires this automatically at `Init` when consent permits tracking. The Web SDK and REST API do not currently emit this event.
>
> **Event name:** `game_launch`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `platform` | `string` | No | OS or mobile platform the game is running on. One of `'Windows'`, `'macOS'`, `'Linux'`, `'iOS'`, `'Android'`. |
> | `is_editor` | `boolean` | No | `true` when the game is running inside the Unity Editor; `false` for shipped builds. Use this to filter dev runs out of production analytics. |
> | `version` | `string` | No | Game version string |
> | `build_guid` | `string` | No | Unity build GUID |
> | `unity_version` | `string` | No | Unity version the build was made with |
> | `os_family` | `string` | No | Host operating system family from Unity's `SystemInfo.operatingSystemFamily`. One of `'Windows'`, `'MacOSX'`, `'Linux'`, `'Other'`. |
> | `device_model` | `string` | No | Hardware model |
> | `gpu` | `string` | No | GPU name |
> | `gpu_vendor` | `string` | No | GPU vendor |
> | `cpu` | `string` | No | CPU name |
> | `cpu_cores` | `integer` | No | Number of CPU cores |
> | `ram_mb` | `integer` | No | System RAM in megabytes |
> | `screen_dpi` | `integer` | No | Display DPI (omitted when 0). |
> | `distribution_platform` | `string` | No | Value of `AudienceConfig.DistributionPlatform` (e.g. `'steam'`, `'epic'`). Omitted if not set. Studio-supplied storefront identifier. Complements the Unity-emitted `platform`, which is the OS-level player runtime. |
> | `idfv` | `string` | No | iOS only. Identifier for Vendor, a device ID scoped to your publisher. Reset when all apps from the same publisher are uninstalled. |
> | `android_id` | `string` | No | Android only. Android device unique identifier. |
>
> On mobile with `EnableMobileAttribution = true`, additional attribution signals are included. See [Attribution Signals](#attribution-signals) for the full set.
>
> **Postback forwarding:** when [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md) are configured for the game, attributed `game_launch` events are forwarded to the configured ad network as a registration/install signal. See [Outbound Forwarding](#outbound-forwarding).
>
> Fired automatically by `ImmutableAudience.Init`. Studios do not call this directly. The wire payload includes the full Unity property set:
>
> ```json theme={null}
> {
>   "type": "track",
>   "eventName": "game_launch",
>   "properties": {
>     "platform": "Windows",
>     "is_editor": false,
>     "version": "1.2.0",
>     "build_guid": "00000000-0000-0000-0000-000000000000",
>     "unity_version": "2022.3.10f1",
>     "os_family": "Windows",
>     "device_model": "PC",
>     "gpu": "Generic GPU",
>     "gpu_vendor": "Generic",
>     "cpu": "Generic CPU",
>     "cpu_cores": 8,
>     "ram_mb": 16384,
>     "screen_dpi": 96,
>     "distribution_platform": "steam"
>   }
> }
> ```

> [accordion] session\_start Unity SDK
>
> Fires when a new session begins. The Unity SDK fires it on `Init`, consent upgrade from `None`, or resume after a pause longer than 30 seconds. The Web SDK does not emit this event; it attaches a `sessionId` to every message instead (see [Auto-attached metadata](#auto-attached-metadata)) and session boundaries are derived from that.
>
> | Property | Type | Description |
> | - | - | - |
> | `session_id` | `string` | Unity SDK only, deprecated. Use the top-level `sessionId` field instead, see [Auto-attached metadata](#auto-attached-metadata). |

> [accordion] session\_end Unity SDK
>
> Fires when a session ends. Only fires when consent is at `Anonymous` or higher. The Unity SDK fires it when `Shutdown` is called, consent is downgraded to `None`, or a session rolls due to extended pause. The Web SDK does not emit this event.
>
> | Property | Type | Description |
> | - | - | - |
> | `session_id` | `string` | Deprecated. Use the top-level `sessionId` field instead, see [Auto-attached metadata](#auto-attached-metadata). |
> | `duration_sec` | `number` | Engagement seconds since `session_start`, wall-clock minus accumulated pause time |

> [accordion] session\_heartbeat Unity SDK
>
> Fires every 60 seconds while the game is focused. Pause and resume reset the heartbeat clock, so wall-clock and reported engagement time can diverge.
>
> | Property | Type | Description |
> | - | - | - |
> | `session_id` | `string` | Deprecated. Use the top-level `sessionId` field instead, see [Auto-attached metadata](#auto-attached-metadata). |
> | `duration_sec` | `number` | Engagement seconds since `session_start`, wall-clock minus accumulated pause time |
>
> Used to estimate playtime per session for studios where players regularly leave the game backgrounded. The Web SDK does not emit this event.

> [accordion] tracking\_authorization\_changed Unity SDK
>
> ATT authorization status changed from its previously recorded value. Does not fire on first launch. The initial state is reported by `game_launch`.
>
> **Requires:** `EnableMobileAttribution = true`, `Anonymous` or `Full` consent, iOS only.
>
> **Event name:** `tracking_authorization_changed`
>
> | Property | Type | Consent | Description |
> | - | - | - | - |
> | `previous_status` | `string` | `Anonymous`+ | Prior ATT status: `notDetermined`, `restricted`, `denied`, or `authorized` |
> | `new_status` | `string` | `Anonymous`+ | New ATT status |
> | `idfa` | `string` | `Full` | Present only when transitioning to `authorized` with `Full` consent |

> [accordion] install\_referrer\_received Unity SDK
>
> Android Play Install Referrer captured. Fires once per install. On first launch the Play Services fetch is usually still in flight when `game_launch` fires, so the event typically arrives on the second launch.
>
> **Requires:** `EnableMobileAttribution = true`, `Full` consent, Android only.
>
> **Event name:** `install_referrer_received`
>
> | Property | Type | Description |
> | - | - | - |
> | `install_referrer` | `string` | Raw referrer string from Google Play (e.g. `utm_source=google-play&utm_medium=organic`) |

> [accordion] page Web SDK
>
> Call `page()` manually on each route change.
>
> | Property | Type | Web SDK | Description |
> | - | - | - | - |
> | `utm_source` | `string` | Once per session | UTM source parameter from URL |
> | `utm_medium` | `string` | Once per session | UTM medium parameter from URL |
> | `utm_campaign` | `string` | Once per session | UTM campaign parameter from URL |
> | `utm_term` | `string` | Once per session | UTM term parameter from URL |
> | `utm_content` | `string` | Once per session | UTM content parameter from URL |
> | `gclid` | `string` | Once per session | Google Ads click ID |
> | `fbclid` | `string` | Once per session | Meta click ID |
> | `ttclid` | `string` | Once per session | TikTok click ID |
> | `rdt_cid` | `string` | Once per session | Reddit click ID |
> | `msclkid` | `string` | Once per session | Microsoft click ID |
> | `dclid` | `string` | Once per session | Display & Video 360 click ID |
> | `li_fat_id` | `string` | Once per session | LinkedIn click ID |
> | `twclid` | `string` | Once per session | X click ID |
> | `referrer` | `string` | Once per session | Referring page URL |
> | `landing_page` | `string` | Once per session | Entry point URL |
> | `referral_code` | `string` | Once per session | Custom referral link parameter |
> | `touchpoint_type` | `string` | Once per session | `'click'` when any click ID or UTM parameter is present |
> | `ga_client_id` | `string` | Every page | Google Analytics client ID (from `_ga` cookie) |
> | `fb_click_id` | `string` | Every page | Facebook click ID (from `_fbc` cookie) |
> | `fb_browser_id` | `string` | Every page | Facebook browser ID (from `_fbp` cookie) |

> [accordion] form\_submitted Web SDK
>
> Fires on HTML form submission. Can be disabled with `autocapture.forms: false`.
>
> | Property | Type | Description |
> | - | - | - |
> | `form_action` | `string` | Form action URL |
> | `form_id` | `string` | Form element ID |
> | `form_name` | `string` | Form element name |
> | `field_names` | `string[]` | Names of form fields |
> | `email_hash` | `string` | SHA-256 hashed email address (`full` consent only) |

> [accordion] scroll\_depth Web SDK
>
> Fires when the user scrolls past a depth milestone (25%, 50%, 75%, 90%, 100%). Each milestone fires at most once per page load. On above-the-fold pages (all content visible without scrolling), fires `depth: 100` with `aboveFold: true` after a 2-second dwell time to filter immediate bounces. Can be disabled with `autocapture.scroll: false`.
>
> | Property | Type | Description |
> | - | - | - |
> | `depth` | `integer` | Milestone reached: 25, 50, 75, 90, or 100 |
> | `aboveFold` | `boolean` | `true` on above-the-fold pages (only present when applicable) |

## Identity Stitching

Each integration assigns an `anonymousId` automatically when tracking begins. As a player moves through your funnel (visiting your marketing site, creating an account, launching the game), identity calls connect those anonymous sessions to a known player in attribution reports.

| Integration | How `anonymousId` is assigned |
| - | - |
| Web SDK | Reads or sets the `imtbl_anon_id` first-party cookie |
| Unity SDK | Generates a persistent GUID stored in `Application.persistentDataPath` |
| REST API | Provided by the caller in the message payload |

Call `identify()` at login to associate the player's `userId` with their activity and traits. A player who logs in on both the marketing site and in-game using the same `userId` will have both session histories attributed to the same profile, no `alias` call needed.

Call `alias()` when the same player is known by different provider IDs across surfaces, for example a player previously identified as a Steam user who later links an email account.

For exact method signatures and the full list of `IdentityType` values, see the API Reference section of the [Web SDK](https://docs.immutable.com/docs/products/audience/analytics/web-sdk.md#api-reference), [Unity SDK](https://docs.immutable.com/docs/products/audience/analytics/unity-sdk.md#api-reference), or [REST API](https://docs.immutable.com/docs/products/audience/analytics/rest-api.md#api-reference) docs.

## Predefined Events

Typed events for common player actions. These schemas apply to the [Web SDK](https://docs.immutable.com/docs/products/audience/analytics/web-sdk.md), the [Unity SDK](https://docs.immutable.com/docs/products/audience/analytics/unity-sdk.md), and the [REST API](https://docs.immutable.com/docs/products/audience/analytics/rest-api.md). Each event accordion below shows the typed call shape for every integration.

Properties are identical across integrations unless noted. Each integration also auto-attaches its own metadata to every event. See [Auto-attached metadata](#auto-attached-metadata) below.

### Event schemas

> [accordion] sign\_up Web SDK

REST API

> Player created a new account.
>
> **Event name:** `sign_up`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `method` | `string` | No | How the player signed up (e.g. `'email'`, `'google'`, `'passport'`) |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.SIGN_UP, { method: 'email' });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "sign_up",
> >   "properties": { "method": "email" }
> > }
> > ```

> [accordion] sign\_in Web SDK

REST API

> Player signed in to an existing account.
>
> **Event name:** `sign_in`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `method` | `string` | No | Authentication method used (e.g. `'email'`, `'google'`, `'passport'`) |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.SIGN_IN, { method: 'google' });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "sign_in",
> >   "properties": { "method": "google" }
> > }
> > ```

> [accordion] purchase Web SDK

Unity SDK

REST API

> Player completed a purchase.
>
> **Event name:** `purchase`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `currency` | `string` | **Yes** | Currency code (e.g. `'USD'`, `'ETH'`) |
> | `value` | `string` | **Yes** | Total purchase value. A numeric-looking string (e.g. `'9.99'`), not a number, to avoid floating-point precision loss. Unity SDK still sends a `decimal` pending a follow-up update. |
> | `item_id` | `string` | No | Unique identifier for the item |
> | `item_name` | `string` | No | Display name of the item |
> | `quantity` | `number` | No | Number of items purchased |
> | `transaction_id` | `string` | No | Your internal transaction reference |
>
> **Postback forwarding:** when [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md) are configured for the game, attributed `purchase` events (including `value` and `currency`) are forwarded to the configured ad network for ROAS optimisation. See [Outbound Forwarding](#outbound-forwarding).
>
> Player buys a sword for \$9.99:
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.PURCHASE, {
> >   currency: 'USD',
> >   value: '9.99',
> >   item_name: 'Legendary Sword',
> >   quantity: 1,
> > });
> > ```
>
> > [tab] Unity SDK
> >
> > ```csharp theme={null}
> > ImmutableAudience.Track(new Purchase
> > {
> >     Currency = "USD",
> >     Value = 9.99m,
> >     ItemName = "Legendary Sword",
> >     Quantity = 1,
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "purchase",
> >   "properties": {
> >     "currency": "USD",
> >     "value": "9.99",
> >     "item_name": "Legendary Sword",
> >     "quantity": 1
> >   }
> > }
> > ```

> [accordion] progression Web SDK

Unity SDK

REST API

> Player started, completed, or failed a level or stage.
>
> **Event name:** `progression`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `status` | `'start' \| 'complete' \| 'fail'` | **Yes** | Whether the player started, completed, or failed this segment |
> | `world` | `string` | No | Top-level grouping (e.g. `'forest'`, `'dungeon'`, `'chapter-1'`) |
> | `level` | `string` | No | Level within the world (e.g. `'3'`, `'boss'`) |
> | `stage` | `string` | No | Sub-level or checkpoint within the level |
> | `score` | `number` | No | Score achieved |
> | `duration_sec` | `number` | No | Time spent in seconds |
>
> Player completed level 3 of the forest world with a score of 4500 in 2 minutes:
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.PROGRESSION, {
> >   status: 'complete',
> >   world: 'forest',
> >   level: '3',
> >   score: 4500,
> >   duration_sec: 120,
> > });
> > ```
>
> > [tab] Unity SDK
> >
> > ```csharp theme={null}
> > ImmutableAudience.Track(new Progression
> > {
> >     Status = ProgressionStatus.Complete,
> >     World = "forest",
> >     Level = "3",
> >     Score = 4500,
> >     DurationSec = 120,
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "progression",
> >   "properties": {
> >     "status": "complete",
> >     "world": "forest",
> >     "level": "3",
> >     "score": 4500,
> >     "duration_sec": 120
> >   }
> > }
> > ```

> [accordion] resource Web SDK

Unity SDK

REST API

> Player gained or spent an in-game resource.
>
> **Event name:** `resource`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `flow` | `'sink' \| 'source'` | **Yes** | `'sink'` when the player spends a resource, `'source'` when they gain one |
> | `currency` | `string` | **Yes** | The resource type (e.g. `'gold'`, `'gems'`, `'energy'`) |
> | `amount` | `number` | **Yes** | Quantity gained or spent |
> | `item_type` | `string` | No | Category of the item involved (e.g. `'weapon'`, `'consumable'`) |
> | `item_id` | `string` | No | Unique identifier for the item |
>
> Player spends 500 gold on a weapon:
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.RESOURCE, {
> >   flow: 'sink',
> >   currency: 'gold',
> >   amount: 500,
> >   item_type: 'weapon',
> >   item_id: 'legendary-sword',
> > });
> > ```
>
> > [tab] Unity SDK
> >
> > ```csharp theme={null}
> > ImmutableAudience.Track(new Resource
> > {
> >     Flow = ResourceFlow.Sink,
> >     Currency = "gold",
> >     Amount = 500,
> >     ItemType = "weapon",
> >     ItemId = "legendary-sword",
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "resource",
> >   "properties": {
> >     "flow": "sink",
> >     "currency": "gold",
> >     "amount": 500,
> >     "item_type": "weapon",
> >     "item_id": "legendary-sword"
> >   }
> > }
> > ```

> [accordion] achievement\_unlocked Web SDK

Unity SDK

REST API

> Player unlocked an achievement.
>
> **Event name:** `achievement_unlocked`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `achievement_id` | `string` | **Yes** | Unique identifier for the achievement |
> | `achievement_name` | `string` | **Yes** | Display name of the achievement |
> | `achievement_type` | `'onboarding' \| 'progression' \| 'mastery' \| 'social' \| 'collection'` | No | Category of the achievement |
>
> Player defeats 100 enemies and unlocks a mastery achievement:
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.ACHIEVEMENT_UNLOCKED, {
> >   achievement_id: 'ach_enemies_100',
> >   achievement_name: '100 Enemies Defeated',
> >   achievement_type: 'mastery',
> > });
> > ```
>
> > [tab] Unity SDK
> >
> > ```csharp theme={null}
> > ImmutableAudience.Track(new AchievementUnlocked
> > {
> >     AchievementId = "ach_enemies_100",
> >     AchievementName = "100 Enemies Defeated",
> >     AchievementType = AchievementType.Mastery,
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "achievement_unlocked",
> >   "properties": {
> >     "achievement_id": "ach_enemies_100",
> >     "achievement_name": "100 Enemies Defeated",
> >     "achievement_type": "mastery"
> >   }
> > }
> > ```

> [accordion] wishlist\_add / wishlist\_remove Web SDK

REST API

> Player added or removed a game from their wishlist.
>
> **Event names:** `wishlist_add`, `wishlist_remove`
>
> **wishlist\_add:**
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `game_id` | `string` | **Yes** | Unique identifier for the game |
> | `source` | `string` | No | Where the action happened (e.g. `'store'`, `'search'`, `'recommendation'`) |
> | `platform` | `string` | No | Platform (e.g. `'steam'`, `'epic'`) |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.WISHLIST_ADD, {
> >   game_id: 'game-123',
> >   source: 'store',
> >   platform: 'steam',
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "wishlist_add",
> >   "properties": { "game_id": "game-123", "source": "store", "platform": "steam" }
> > }
> > ```
>
> **wishlist\_remove:**
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `game_id` | `string` | **Yes** | Unique identifier for the game |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.WISHLIST_REMOVE, { game_id: 'game-123' });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "wishlist_remove",
> >   "properties": { "game_id": "game-123" }
> > }
> > ```

> [accordion] email\_acquired Web SDK

REST API

> Captured a player's email address (e.g. from a newsletter signup or waitlist form).
>
> **Event name:** `email_acquired`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `source` | `string` | No | Where the email was collected (e.g. `'waitlist'`, `'newsletter'`, `'checkout'`) |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.EMAIL_ACQUIRED, { source: 'waitlist' });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "email_acquired",
> >   "properties": { "source": "waitlist" }
> > }
> > ```

> [accordion] game\_page\_viewed Web SDK

REST API

> Player viewed a game page.
>
> **Event name:** `game_page_viewed`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `game_id` | `string` | **Yes** | Unique identifier for the game |
> | `game_name` | `string` | No | Display name of the game |
> | `slug` | `string` | No | URL-friendly identifier (e.g. `'my-game'`) |
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.GAME_PAGE_VIEWED, {
> >   game_id: 'game-123',
> >   game_name: 'My Game',
> >   slug: 'my-game',
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "game_page_viewed",
> >   "properties": { "game_id": "game-123", "game_name": "My Game", "slug": "my-game" }
> > }
> > ```

> [accordion] link\_clicked Web SDK

REST API

> Player clicked a link. Fires automatically for outbound link clicks (external domains only) via auto-capture — disable with `autocapture.clicks: false` — or manually via `track()`/the REST API for links auto-capture can't see (e.g. non-anchor elements, server-rendered redirects).
>
> **Event name:** `link_clicked`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `url` | `string` | **Yes** | Destination URL |
> | `label` | `string` | No | Display text or label for the link |
> | `source` | `string` | No | Where the link appeared (e.g. `'navbar'`, `'footer'`, `'cta-banner'`) |
> | `element_id` | `string` | No | DOM id of the clicked element. Only set by auto-capture |
> | `outbound` | `boolean` | No | Whether the link led off-site. Only set by auto-capture |
>
> Auto-captured clicks also carry the session's attribution signals (`utm_*`, click IDs, `referrer`, `landing_page`, `referral_code`, `touchpoint_type`).
>
> > [tab] Web SDK
> >
> > ```typescript theme={null}
> > audience.track(AudienceEvents.LINK_CLICKED, {
> >   url: 'https://store.steampowered.com/app/123',
> >   label: 'Wishlist on Steam',
> >   source: 'cta-banner',
> > });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "link_clicked",
> >   "properties": {
> >     "url": "https://store.steampowered.com/app/123",
> >     "label": "Wishlist on Steam",
> >     "source": "cta-banner"
> >   }
> > }
> > ```

> [accordion] milestone\_reached Unity SDK

REST API

> Player reached a named milestone or achievement. Use for any named accomplishment that does not fit the start/complete/fail shape of `progression`. Covers both **one-shot** achievements (e.g. `first_boss_defeated`, `tutorial_complete`, `100_percent_completion`) and **recurring** named milestones (e.g. `character_<id>_level_<N>`, `prestige_tier_<N>`, `streak_day_<N>`, `pvp_rank_<tier>`). Parameterise `name` for the recurring case so each instance is distinguishable in analytics.
>
> **Event name:** `milestone_reached`
>
> | Property | Type | Required | Description |
> | - | - | - | - |
> | `name` | `string` | **Yes** | Milestone identifier. One-shot example: `'first_boss_defeated'`. Recurring example: `'character_aria_level_5'` |
>
> Player defeats the first boss:
>
> > [tab] Unity SDK
> >
> > ```csharp theme={null}
> > ImmutableAudience.Track(new MilestoneReached { Name = "first_boss_defeated" });
> > ```
>
> > [tab] REST API
> >
> > ```json theme={null}
> > {
> >   "type": "track",
> >   "eventName": "milestone_reached",
> >   "properties": { "name": "first_boss_defeated" }
> > }
> > ```
>
> The Web SDK does not yet ship a typed equivalent. Studios on that surface can emit the same event by passing the event name directly.

### Auto-attached metadata

The Web SDK and Unity SDK auto-attach a shared baseline to every event, including `identify()`/`Identify()` and `alias()`/`Alias()` calls:

* A persistent anonymous device identifier (`anonymousId`)
* The current session identifier (`sessionId`)
* An integration tag identifying the SDK source
* The library identifier and version
* Locale, screen size, timezone, and user-agent string

The Web SDK additionally captures browser page context (current page URL, path, referrer, and title) on every event. The tabs below document only the integration-specific additions on top of that baseline.

The backend additionally stamps `received_at` and IP-derived geo on every event regardless of integration.

> [tab] Web SDK
>
> | Method call | Auto-attached |
> | - | - |
> | `track('sign_up', ...)`, `track('link_clicked', ...)` | [Attribution signals](#attribution-signals) from the session's first-touch snapshot |
> | every `track()` call after `identify()` (Full consent only) | `userId` |
>
> > [!NOTE]
> >
> > Attribution is the session's first-touch snapshot, captured at session start. A player who arrives via `?utm_source=discord`, navigates to another page, then triggers `sign_up` still carries `utm_source=discord` on that event, and `landing_page` is included.

> [tab] Unity SDK
>
> | Method call | Auto-attached |
> | - | - |
> | every `Track` call after `Identify` (Full consent only) | `userId` |
>
> The shared baseline `context` is computed once at `Init` and attached unchanged to every event, rather than reassembled per call.

## Consent Model

All Audience integrations use a three-tier consent model. Consent defaults to None and can be changed at any time. Changes take effect immediately. The Audience integrations do not provide a consent UI. You are responsible for building the cookie banner or privacy prompt and setting the consent level when the user makes a choice.

| Level | What it does | When to set |
| - | - | - |
| **None** | Loads but collects nothing | Before consent is given or when consent is denied |
| **Anonymous** | Tracks activity without user identity | After analytics consent |
| **Full** | Tracks everything including user identity | After full tracking consent |

Native games do not have a cookie banner. Studios typically gate the consent call on a first-launch privacy prompt or a settings menu.

### Downgrading Consent

You can downgrade consent at any time. All integrations share this core behavior:

* **Full → Anonymous:** strips player identity from queued events, removes pending `identify()` and `alias()` messages.
* **Any level → None:** purges all queued events.

> [tab] Web SDK
>
> Clears local state (cookies and identity) so no tracking artifacts remain on the device.

> [tab] Unity SDK
>
> Fires `session_end` on downgrade to `None`, then stops emitting until consent is restored. `AnonymousId` persists in native local storage across downgrades so a later upgrade resumes the same anonymous identity rather than minting a fresh one.

> [tab] REST API
>
> Consent state is the caller's responsibility. The API has no client-side state to clear on downgrade.

The tables below show whether each data category is collected at each consent level.

> [tab] Web SDK
>
> | Data | `'none'` | `'anonymous'` | `'full'` |
> | - | - | - | - |
> | Cookies | None | `imtbl_anon_id`, `_imtbl_sid` | `imtbl_anon_id`, `_imtbl_sid` |
> | Device fingerprint | No | Yes | Yes |
> | Attribution signals | No | Yes | Yes |
> | `page()` | No | Yes | Yes |
> | `track()` | No | Yes | Yes |
> | Outbound link clicks | No | Yes | Yes |
> | Form submissions | No | Yes (no email) | Yes (hashed email) |
> | Scroll depth milestones | No | Yes | Yes |
> | Third-party ID stitching | No | Yes | Yes |
> | `identify()` | No | No | Yes |
> | `alias()` | No | No | Yes |

> [tab] Unity SDK
>
> | Data | `None` | `Anonymous` | `Full` |
> | - | - | - | - |
> | Local storage | `AnonymousId` only | `AnonymousId`, queued events | `AnonymousId`, queued events |
> | Session events (`session_start`, `session_heartbeat`, `session_end`) | No | Yes | Yes |
> | `game_launch` (auto at `Init`) | No | Yes | Yes |
> | Device fingerprint (CPU, GPU, RAM, OS, Unity version) | No | Yes (in `game_launch`) | Yes (in `game_launch`) |
> | Custom `Track` calls | No | Yes | Yes |
> | `Identify` (player identity) | No | No | Yes |
> | IDFV, Android device ID (all mobile builds) | No | Yes (in `game_launch`) | Yes (in `game_launch`) |
> | ATT status, SKAdNetwork registration (iOS attribution builds) | No | Yes (in `game_launch`) | Yes (in `game_launch`) |
> | IDFA (iOS, attribution builds) | No | No | Yes, when ATT `authorized` |
> | GAID, Install Referrer (Android, attribution builds) | No | No | Yes, from second launch (unless user opted out of ad personalization) |

> [tab] REST API
>
> Consent is your responsibility to enforce. The API processes only what you explicitly send. See [REST API: Consent](https://docs.immutable.com/docs/products/audience/analytics/rest-api.md#consent) for the consent endpoints.

## Outbound Forwarding

Most data collected by Audience integrations stays within Immutable. The exception is when [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md) are configured for a game: attributed `game_launch` and `purchase` events are forwarded server-to-server to the configured ad network (TikTok Ads, Reddit Ads).

Forwarded payloads contain only the fields each ad network requires for conversion matching:

| Forwarded field | Source |
| - | - |
| Click ID (`ttclid` for TikTok Ads, `rdt_cid` for Reddit Ads) | Captured by the Web SDK from the URL when a player arrived from a paid ad |
| Event name (mapped to the network's taxonomy) | The originating `game_launch` or `purchase` event |
| `value` and `currency` | The `purchase` event's `value` and `currency` properties |
| Hashed email (Reddit Ads only, when no click ID is present) | The player's `identify()` email, hashed with SHA-256 |

Player names, raw emails, device fingerprints, session details, and event properties beyond the table above are **not** forwarded. Only events from players at `anonymous` or `full` consent are eligible. Forwarding requires explicit per-game configuration in [Audience Hub](https://hub.immutable.com); no postbacks fire for games without an active configuration.

See [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md) for setup, supported networks, and delivery monitoring.

## What Is Not Collected

None of the Audience integrations collect the following:

* No cross-domain tracking (first-party cookies only)
* No session replay or screen recording
* No heatmaps or mouse movement tracking
* No A/B testing or feature flags
* No impression or view-through tracking (click-through only)
* No raw email addresses (only SHA-256 hashed, only at `full` consent)

## Next Steps

> [card] [Attribution](https://docs.immutable.com/docs/products/attribution/overview.md)
>
> How tracking data powers player attribution and Hub reports

> [card] [Web SDK](https://docs.immutable.com/docs/products/audience/analytics/web-sdk.md)
>
> Typed SDK for web games, marketing sites, and SPAs

> [card] [Unity SDK](https://docs.immutable.com/docs/products/audience/analytics/unity-sdk.md)
>
> In-game tracking for Unity games on PC and mobile.

> [card] [REST API](https://docs.immutable.com/docs/products/audience/analytics/rest-api.md)
>
> Send events from your backend or game server

> [card] [Conversion Postbacks](https://docs.immutable.com/docs/products/attribution/postbacks/overview.md)
>
> Send attributed conversions back to ad networks to improve campaign optimisation


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.