# Data dictionary

One row is one continuous appearance of an ad on screen; if it leaves the viewport and returns, that is a new row. Columns are grouped by what they tell you. Where mobile and desktop name the same thing differently, both names sit in one row. [See a whole row →](/docs)

A column with no tag is on every row. **Mobile** or **Desktop** marks a column that only one platform's rows carry. A null column is left out of the line: treat a missing key as null. The one exception is `other_brands`, which is `[]` when there are none.

`impression_id` is unique within an export. A rebuilt day can give its rows new ids, so merge by day, not by id: [A daily loader →](/docs/integration#5-load-and-replace-by-day)

Mobile rows have 22 columns; desktop rows have 23.

## Identity

Keys for joining and counting. `panelist_id` and `session_id` are stable across exports; a rebuilt day can give its rows new `impression_id` values.

### `impression_id` (string; mobile and desktop)

Unique identifier of the impression, unique within an export. A rebuilt day can give its rows new ids: merge by day, not by id.

Example: `impression_id` = `9f1c2b3a…4b5c6d7e`

### `panelist_id` (string; mobile and desktop)

Pseudonymous identifier of the panelist who saw the ad. The same across every export and both platforms, so it counts reach and frequency.

Example: `panelist_id` = `p_0001a2b3`

### `session_id` (integer on mobile, string on desktop; mobile and desktop)

The sitting the impression happened in: a period of phone use, or a browsing session.

Example: `session_id` = `174823910`

## Where the ad was seen

### `hostname` (string; mobile and desktop)

The website the ad was seen on.

**Null** on mobile when the ad was seen inside an app rather than in a browser.

Example: `hostname` = `aftonbladet.se`

### `package_name` (string; mobile)

The Android app that was on screen, by its package id.

Example: `package_name` = `com.instagram.android`

### `ad_technical_format` (string; desktop)

What kind of ad it was: `display`, `in-stream` (video inside a video player) or `out-stream` (video in the page).

Example: `ad_technical_format` = `display`

## When and for how long

All times are UTC. Rows carry no date column: the download holds a `day=DD` folder per day inside each month's archive, the UTC date the ad first appeared.

### `first_seen` (timestamp; mobile) · `first_event_at` (timestamp; desktop)

When the ad first appeared.

Example: `first_seen` = `2026-10-03T09:42:11.412Z`; `first_event_at` = `2026-10-03T18:05:12.031Z`

### `last_seen` (timestamp; mobile) · `last_event_at` (timestamp; desktop)

When the ad left the screen. On mobile, the device's next screen change after the ad was last captured, in the same app or another, at most 60 seconds later and 10 minutes after `first_seen`, and earlier when the camera stopped. On desktop, when the ad was last seen.

Example: `last_seen` = `2026-10-03T09:42:14.778Z`; `last_event_at` = `2026-10-03T18:05:19.874Z`

### `duration_s` (double, seconds; mobile) · `time_in_screen` (integer, milliseconds; desktop)

How long the ad was on screen: `first_seen` to `last_seen` on mobile.

Mind the units: seconds on mobile, milliseconds on desktop.

Example: `duration_s` = `3.366`; `time_in_screen` = `6120`

### `first_pixel_inview_at` (timestamp; desktop) · `last_pixel_inview_at` (timestamp; desktop)

When any part of the ad first and last became visible.

Example: `first_pixel_inview_at` = `2026-10-03T18:05:12.540Z`; `last_pixel_inview_at` = `2026-10-03T18:05:18.660Z`

## Ad size

### `width_dp` (integer, dp; mobile) · `width` (integer, CSS px; desktop)

Width of the ad. Mobile uses density-independent pixels, so sizes compare across screens.

Example: `width_dp` = `360`; `width` = `300`

### `height_dp` (integer, dp; mobile) · `height` (integer, CSS px; desktop)

Height of the ad.

Example: `height_dp` = `450`; `height` = `250`

### `ad_area_pct` (double, percent; mobile)

Share of the screen the ad covered. `48.6` means 48.6%.

Example: `ad_area_pct` = `48.6`

## Viewability

The IAB in-view standard, measured in the panelist's browser.

### `exist_viewable_1_s_threshold_50` (boolean; desktop)

At least half the ad was visible for at least one continuous second.

Example: `exist_viewable_1_s_threshold_50` = `true`

### `exist_viewable_2_s_threshold_50` (boolean; desktop)

At least half the ad was visible for at least two continuous seconds.

Example: `exist_viewable_2_s_threshold_50` = `true`

### `is_iab_inview` (boolean; desktop)

Whether the ad meets the IAB standard for its format: one second for display, two for video.

Example: `is_iab_inview` = `true`

## Attention

Gaze measured while the ad was on screen, `first_seen` to `last_seen` on mobile, with the same definitions on both platforms. [How we measure →](/docs/methodology)

### `eyetracker_enabled` (boolean; mobile and desktop)

`true` when gaze was measured while the ad was on screen. Filter on it before computing attention rates.

**When false**, the attention columns are zero or null. That means "not measured", not "not looked at".

Example: `eyetracker_enabled` = `true`

### `fixation_duration_ms` (integer, ms; mobile) · `total_fixation_duration_ms` (integer, ms; desktop)

Total time the gaze rested on the ad while it was on screen, in milliseconds. Fixation time is measured from the first to the last gaze sample on the ad, so a single fixation reads slightly shorter than the time the eye rested there.

Example: `fixation_duration_ms` = `412`; `total_fixation_duration_ms` = `690`

### `is_fixated` (boolean; mobile and desktop)

Whether the ad was looked at. The same definition on mobile and desktop, so the two compare directly.

Example: `is_fixated` = `true`

### `fixation_count` (integer; desktop)

How many separate times the gaze landed on the ad.

Example: `fixation_count` = `3`

### `first_fixation_at` (timestamp; desktop) · `last_fixation_at` (timestamp; desktop)

When the gaze first landed on the ad, and when it last left.

**Null** when the ad was not looked at.

Example: `first_fixation_at` = `2026-10-03T18:05:13.102Z`; `last_fixation_at` = `2026-10-03T18:05:16.410Z`

## Audience

### `demographics` (object; mobile and desktop)

The panelist's profile on the day of the impression: `age`, `gender`, `area`, `country_code`, and nothing else. Each can be null when the panelist has not given it.

Example: `demographics` = `{ "age": 34, … }`

## The ad

Who advertised and what the ad said. Read from the text and links captured with each ad. A day's brand reading finishes about two days after the day; until then these columns can be missing, and the day's rebuild brings them.

### `brand` (string; mobile)

The advertiser, by its public name.

**Null** when the ad shows no readable advertiser, for example an image ad with no text. The row stays in the export.

Example: `brand` = `Oddset`

### `brand_evidence` (object; mobile)

The exact text the brand was read from, keyed by where it was found: `account_name`, `ad_copy`, `landing_domain`, `file_name`, `view_id`.

**Null** when `brand` is null.

Example: `brand_evidence` = `{"account_name": ["oddset"]}`

### `other_brands` (array of object; mobile)

Other brands named in the ad, such as the phone in an operator's ad. Each has a `name` and its `relation` to the ad: `product`, `retailer_listing`, `co_marketing`, `comparison`, `sponsorship` or `unknown`.

**Empty list** `[]` when there are none, also on a row with no `brand`. The one column that is never left out for being empty.

Example: `other_brands` = `[{"name": "iPhone 17", "relation": "product"}]`

### `industry` (string; mobile) · `industry_path` (string; mobile)

The advertiser's industry on the IAB Ad Product Taxonomy 2.0: the top level, and the full path down to the most specific level that fits.

**Null** when there is no brand, or the advertiser could not be placed with confidence.

Example: `industry` = `Gambling`; `industry_path` = `Gambling > Sports Betting`

### `ad_text` (string; mobile)

The advertiser's own words in the ad, copied exactly, one piece of text per line.

**Null** when there is no brand.

Example: `ad_text` = `Allsvenskan avgörs nu\nSpela på Oddset`

### `creative_url` (string, URL; mobile)

Address of the ad's image or video file, when the app exposes one.

Example: `creative_url` = `https://scontent…/oddset_v41.jpg`

### `html_metadata` (object; desktop)

Content of the ad's HTML: visible text, headings, links, image, video and script addresses. Only included when the export is started with `include_html_metadata` and your agreement covers it.

Example: `html_metadata` = `{ "headings": […], … }`
