> For the complete documentation index, see [llms.txt](https://docs.mediarithmics.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/design-your-data-model-and-schema/user-identity/user-identifiers/user-device.md).

# User Device

The device graph, and the identifier formats you send for browsers, apps, CTV, and network IDs.

## Your goal

Send device identifiers in the exact format the platform expects, so they land on the right device point and can be used to recognise the user.

## Expected outcome

Each device identifier you send resolves to a registry that exists, and appears on the UserPoint as a device technical identifier.

## The device graph

In each datamart, all device information is stored in a device graph:

* Devices are represented by **UserDevicePoint**.
* Device identifiers are represented by **UserDeviceTechnicalId**.

A UserPoint can have multiple device points; a device point can have multiple device technical identifiers and one set of device information.

```
UserPoint
|
|---------UserDevicePoint--------------------------DeviceInfo: PC - CHROME BROWSER
|                |---------UserDeviceTechnicalId: 1P cookie
|                |---------UserDeviceTechnicalId: Network ID
|                |---------UserDeviceTechnicalId: 3P cookie
|
|---------UserDevicePoint--------------------------DeviceInfo: ANDROID TABLET
|                |---------UserDeviceTechnicalId: Mobile advertising id
|                |---------UserDeviceTechnicalId: Mobile vendor id
```

{% hint style="info" %}
Two web browsers on the same desktop computer are **two distinct agents**: Chrome on a Windows laptop is a different device from Firefox on the same laptop. On a smartphone, the web browser and the phone itself are also two distinct agents.
{% endhint %}

Every device technical identifier belongs to a **registry**, which decides what kind of identifier it is. Registries and their types are covered in [Device registries](/setup-and-monitor/plan-and-integrate/set-up-the-environment/set-up-device-registries.md).

## The documents, as the API returns them

<details>

<summary>UserDevicePoint</summary>

| Property                | Type                        | Description                                                                     |
| ----------------------- | --------------------------- | ------------------------------------------------------------------------------- |
| `id`                    | String                      | The document identifier, formatted as `udp:-1234`.                              |
| `type`                  | Enum `UserIdentifierType`   | For device points, `"USER_DEVICE_POINT"`.                                       |
| `creation_ts`           | Timestamp                   | When the device point was created.                                              |
| `last_activity_ts`      | Timestamp                   | Last time an event was ingested from this device. ⚠️ Not updated at the moment. |
| `device`                | Object of type `DeviceInfo` | Description of the device through normalised properties.                        |
| `technical_identifiers` | List of objects             | The available identifiers for the device.                                       |

</details>

<details>

<summary>The <code>device</code> property (DeviceInfo)</summary>

| Property          | Type                         | Description                                                                                                                                       |
| ----------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `brand`           | String                       | The brand of the device, for example "Apple".                                                                                                     |
| `model`           | String                       | The model, for example "Iphone 14".                                                                                                               |
| `agent_type`      | Enum `UserAgentType`         | `WEB_BROWSER`, `MOBILE_APP`, or `CTV_APP`.                                                                                                        |
| `browser_family`  | Enum `BrowserFamily`         | If the device is a browser: `OTHER`, `CHROME`, `IE`, `FIREFOX`, `SAFARI`, `OPERA`, `STOCK_ANDROID`, `BOT`, `EMAIL_CLIENT`, `MICROSOFT_EDGE`.      |
| `browser_version` | String                       | The version of the browser.                                                                                                                       |
| `form_factor`     | Enum `FormFactor`            | `PERSONAL_COMPUTER`, `SMART_TV`, `GAME_CONSOLE`, `SMARTPHONE`, `TABLET`, `WEARABLE_COMPUTER`, `OTHER`.                                            |
| `os_family`       | Enum `OperatingSystemFamily` | `WINDOWS`, `MAC_OS`, `LINUX`, `ANDROID`, `IOS`, `TIZEN`, `WEB_OS`, `ANDROID_TV`, `GOOGLE_TV`, `TV_OS`, `FIRE_TV`, `ROKU_TV`, `TITAN_OS`, `OTHER`. |
| `os_version`      | String                       | The version of the operating system, for example "macOS 10.15 Catalina".                                                                          |
| `carrier`         | String                       | The service provider ensuring connectivity of the device.                                                                                         |

</details>

<details>

<summary>UserDeviceTechnicalId</summary>

| Property           | Type                | Description                                                                                                 |
| ------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `user_agent_id`    | String              | The value of the identifier - see the formats below.                                                        |
| `registry_id`      | String              | The registry the technical identifier belongs to.                                                           |
| `type`             | Enum `RegistryType` | The type of that registry.                                                                                  |
| `creation_ts`      | Timestamp           | When the document was created.                                                                              |
| `last_activity_ts` | Timestamp           | Last time an event was ingested with this identifier. ⚠️ Not updated at the moment.                         |
| `expiration_ts`    | Timestamp           | When the document expires. ℹ️ For the moment, technical IDs are stored for **1 year** after their creation. |

</details>

{% hint style="info" %}
The properties available in these documents can differ slightly from those of the runtime schema.
{% endhint %}

## `user_agent_id` formats

`user_agent_id` packs several pieces of information - registry type, registry ID, and the value - into a single property. Sending the wrong shape is the most common reason a device identifier does not resolve.

### Cookie-based identifiers

**Installation ID** - the first-party cookie generated by mediarithmics. It appears in three forms depending on where it is used:

| Location                                                         | Value format                                           | Example                                                       |
| ---------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------- |
| Cookie stored in the user's browser                              | `<version_prefix><base64(value)>`                      | `aMGQ0YTU4Y2EtMTRlNS0xMWVlLWJlNTYtMDI0MmFjMTIwMDAy`           |
| Used in authenticated endpoints                                  | `ins:<registry_id>:<value>`                            | `ins:1001:0d4a58ca-14e5-11ee-be56-0242ac120002`               |
| Stored in mediarithmics, and used in non-authenticated endpoints | `ins:<registry_token>:<version_prefix><base64(value)>` | `ins:first:aMGQ0YTU4Y2EtMTRlNS0xMWVlLWJlNTYtMDI0MmFjMTIwMDAy` |

`version_prefix` is currently defined as `a`.

**Vector ID** - the mediarithmics third-party cookie. Two equivalent formats: `vec:<value>` is the exact format stored in the cookie, `mum:<value>` is the format stored as a technical identifier in the datamart. For example `vec:89998434` / `mum:89998434`.

For a device point, the vector ID can be retrieved in the `technical_identifiers` list as a device technical ID of type `MUM_ID` - in which case the format is `mum:89998434` - or in the `mappings` list related to the device point.

**Partners' third-party cookies** - for historical reasons, Google and Xandr advertising cookies have their own prefixes:

* `tech:goo:<value>` for Google advertising cookies
* `tech:apx:<value>` for Xandr advertising cookies

For other partners, the third-party cookie value is attached to a web domain defined by mediarithmics: `web:<web_domain_id>:<value>`, where the web domain designates `partner-domain.com` and `value` is the identifier inside the cookie on that domain.

### Mobile application identifiers

**Mobile advertising IDs** - `mob:<os>:<encoding>:<value>`

* `os` - `and` for Android, `ios` for iOS.
* `encoding` - `raw` for none, `sha1` for SHA1, `md5` for MD5.
* `value` - the advertising ID, encoded according to `encoding`. The non-encoded ID should be **lower case for Android** and **upper case for iOS**.

```
mob:ios:raw:12345654-ABCD-1234-A1B2-123456789876
mob:and:raw:12345678-abcd-1234-a1b2-123456789876
```

**Mobile vendor IDs** - `mov:<os>:<registry_id>:<value>`, where `registry_id` designates the registry the device ID should be linked to, and `value` is the identifier generated inside the mobile application.

### CTV identifiers

* CTV advertising IDs - `tv:<registry_id>:<value>`
* IP addresses captured on a CTV channel - `ipv4:<registry_id>:<value>` for registries of type `IPV4_ADDRESS_ID`, and `ipv6:<registry_id>:<value>` for `IPV6_ADDRESS_ID`. The value is the raw IP address, with no hashing or normalisation.

{% hint style="info" %}
There is no registry dedicated to CTV vendor identifiers, but you can use custom registries, or mobile vendor ones if you want the `os` value inside the identifier.
{% endhint %}

### Other device identifiers

* `net:<registry_id>:<value>` for device technical IDs of type `NETWORK_ID`
* `dev:<registry_id>:<value>` for `CUSTOM_DEVICE_ID`
* `udp:<value>` to use the device point identifier directly instead of a custom device identifier

## Merging device points

When two device technical IDs are associated, their device points are merged. This happens when capturing user activities carrying multiple identifiers, and when using the identifier association feature.

If the device points involved are linked to different UserPoints, merging them also triggers a [merge of the UserPoints](/setup-and-monitor/collect-and-manage-your-data/design-your-data-model-and-schema/user-identity/userpoint-and-identity-graph.md#userpoint-merges).

## Retrieving third-party cookie mappings

The `ThirdPartyCookieMappings` schema function retrieves third-party cookie mappings for a device point. It works on device points carrying a device technical ID of type `MUM_ID`: it translates the `MUM_ID` into a `vector_id` - `mum:-1234` becomes `vec:1234` - and retrieves the attached partners' third-party cookies.

```graphql
type UserDevicePoint  {
  id: ID! @TreeIndex(index:"USER_INDEX")
  mappings: [UserAgentMapping!]! @Function(name:"ThirdPartyCookieMappings", params:["id"])
}

type UserAgentMapping  {
   last_seen: Timestamp
   user_agent_id: String
   vector_id: String
}
```

## The legacy user agent format

{% hint style="warning" %}
**User agent** is a legacy format being replaced by user device points and user device technical identifiers. New integrations should use device points.
{% endhint %}

Several user agents can be attached to a UserPoint, each with a device info object, and all of them identified by a vector ID:

```
UserPoint
|
|---------UserAgent: vec:1111--------------------------DeviceInfo: PC - CHROME BROWSER
|
|---------UserAgent: vec:2222--------------------------DeviceInfo: ANDROID TABLET
```

| Property      | Type      | Description                                                                                                             |
| ------------- | --------- | ----------------------------------------------------------------------------------------------------------------------- |
| `vector_id`   | String    | Unique ID generated by mediarithmics for each agent.                                                                    |
| `device`      | Object    | Device information such as operating system and browser.                                                                |
| `creation_ts` | Timestamp | When the user agent was registered on the platform.                                                                     |
| `mappings`    | Array     | Additional identifiers - the device mappings: cookie-based or mobile application identifiers associated with the agent. |

Agent-based operations such as visiting a website or seeing an ad generally use the user agent to identify the user automatically. You can also use an agent to identify a user explicitly, usually with a `user_agent_id` field in requests.

## Verify

* Every device identifier you send matches one of the formats above.
* The registry referenced in the identifier exists and is linked to the datamart.
* A test device appears as a UserDevicePoint with the expected `DeviceInfo` and technical identifiers.

## Related pages

<table data-view="cards" data-search="false"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Device registries</strong></td><td>Registry types, and how to create or subscribe.</td><td><a href="/setup-and-monitor/plan-and-integrate/set-up-the-environment/set-up-device-registries.md">Device registries</a></td></tr><tr><td><strong>Network IDs</strong></td><td>Third-party identifiers that live in registries.</td><td><a href="/setup-and-monitor/collect-and-manage-your-data/design-your-data-model-and-schema/user-identity/network-ids.md">Network IDs</a></td></tr><tr><td><strong>Audit our tag's browser footprint</strong></td><td>The cookies the tag sets, and where.</td><td><a href="/setup-and-monitor/ensure-privacy-and-compliance/audit-our-tag-s-browser-footprint.md">Audit our tag's browser footprint</a></td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.mediarithmics.io/setup-and-monitor/collect-and-manage-your-data/design-your-data-model-and-schema/user-identity/user-identifiers/user-device.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
