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

# Stats Coverage by Platform

> Which post-stat and account-stat fields are populated for each connected social platform.

The `PostStats` and `AccountStats` schemas are normalized across every platform Marky supports — but each platform exposes a different subset of metrics. Fields that a platform doesn't support are returned as `null` so your code can parse one shape everywhere.

This page documents which fields actually contain data per platform, and the platform-specific caveats you need to know.

## Post stats — watch metrics

`avg_watch_time_ms`, `total_watch_time_ms`, and `completion_rate` are populated on video posts where the platform exposes the data. `video_duration_ms` is the total length of the video — populated where available so customers can compute their own watch ratios (`avg_watch_time_ms / video_duration_ms`).

| Platform    | `views` | `video_duration_ms` | `avg_watch_time_ms` | `total_watch_time_ms` | `completion_rate` |
| ----------- | :-----: | :-----------------: | :-----------------: | :-------------------: | :---------------: |
| Facebook    |    ✅    |          ❌          |          ✅          |           ✅           |         ✅         |
| Instagram   |    ✅    |          ❌          |          ✅          |           ✅           |         ❌         |
| YouTube     |    ✅    |          ✅          |          ✅          |           ✅           |         ✅         |
| X (Twitter) |    ✅    |          ✅          |          ❌          |           ❌           |         ✅         |
| LinkedIn    |    ✅    |          ❌          |          ✅          |           ✅           |         ❌         |
| Pinterest   |    ✅    |          ❌          |          ✅          |           ❌           |         ✅         |
| TikTok      |    ✅    |          ✅          |          ❌          |           ❌           |         ❌         |

Watch data is only available for recent posts: **30 days back on X**, **6 months back on LinkedIn**. Older posts return `null` for watch fields.

## Account stats — audience demographics

Demographics on `AccountStats` are returned as dictionaries mapping a bucket label to a fraction (0.0–1.0) summing to \~1.0. Fields are `null` for platforms that don't expose them.

Every platform that does expose demographics requires a minimum audience size before any breakdown is returned — Instagram is the strictest at **100 followers**, others require fewer but won't return breakdowns for very small accounts. Below the threshold, all demographic fields return `null` even on supported platforms.

| Platform    | `audience_age_pct` | `audience_gender_pct` | `audience_country_pct` | `audience_city_pct` | `audience_industry_pct` | `audience_seniority_pct` | `audience_function_pct` |
| ----------- | :----------------: | :-------------------: | :--------------------: | :-----------------: | :---------------------: | :----------------------: | :---------------------: |
| Instagram   |          ✅         |           ✅           |            ✅           |          ✅          |            ❌            |             ❌            |            ❌            |
| YouTube     |          ✅         |           ✅           |            ✅           |          ❌          |            ❌            |             ❌            |            ❌            |
| LinkedIn    |          ❌         |           ❌           |            ✅           |          ❌          |            ✅            |             ✅            |            ✅            |
| Pinterest   |        soon        |          soon         |          soon          |          ❌          |            ❌            |             ❌            |            ❌            |
| Facebook    |          ❌         |           ❌           |            ❌           |          ❌          |            ❌            |             ❌            |            ❌            |
| X (Twitter) |          ❌         |           ❌           |            ❌           |          ❌          |            ❌            |             ❌            |            ❌            |
| TikTok      |          ❌         |           ❌           |            ❌           |          ❌          |            ❌            |             ❌            |            ❌            |

### Platform-specific caveats

**Instagram** — Top 45 buckets per dimension. Bucket labels:

* Age: `"13-17"`, `"18-24"`, `"25-34"`, `"35-44"`, `"45-54"`, `"55-64"`, `"65+"`
* Gender: `"F"`, `"M"`, `"U"` (unknown)
* Country: ISO 3166-1 alpha-2 codes (e.g. `"US"`, `"GB"`)
* City: City name strings

**LinkedIn** — Bucket keys are LinkedIn URNs:

* Country: `"urn:li:geo:103644278"` (numeric geo IDs — `103644278` is the US). Not ISO codes.
* Industry: `"urn:li:industry:4"` (Computer Software, etc.)
* Seniority: `"urn:li:seniority:3"` (Senior, etc.)
* Function: `"urn:li:function:4"` (Engineering, etc.)

To resolve URNs to human-readable labels, use the LinkedIn URN taxonomy lookup API.

**YouTube** — Bucket keys use YouTube's native format:

* Age: `"age13-17"`, `"age18-24"`, `"age25-34"`, etc.
* Gender: `"male"`, `"female"`, `"user_specified"`, `"gender_other"`
* Country: ISO 3166-1 alpha-2 codes (e.g. `"US"`, `"GB"`)

**Pinterest** — Demographic fields are defined on the response schema but not yet populated. Coming in a future release.

**Facebook, X, TikTok** — These platforms don't expose audience demographics through their APIs. Fields will always be `null`.

## Example post-stat responses

### Instagram Reel

Watch fields only populate for `REELS` and `VIDEO` media types. Carousels and feed photos return `null` for all watch fields. Instagram does not surface a `completion_rate` or `video_duration_ms`.

```json theme={null}
{
  "publish_id": "17882999205416177",
  "platform": "instagram",
  "type": "Reel",
  "stats": {
    "likes": 84,
    "comment_count": 7,
    "shares": 12,
    "saves": 23,
    "reach": 1421,
    "impressions": 1873,
    "views": 1421,
    "video_duration_ms": null,
    "avg_watch_time_ms": 6230,
    "total_watch_time_ms": 1245000,
    "completion_rate": null
  }
}
```

### Facebook video (full watch coverage)

Facebook does not expose `video_duration_ms` in the response we use for stats. The other watch fields are populated.

```json theme={null}
{
  "publish_id": "1234567890",
  "platform": "facebook",
  "type": "Video",
  "stats": {
    "likes": 142,
    "comment_count": 8,
    "shares": 23,
    "views": 1000,
    "impressions": 1834,
    "video_duration_ms": null,
    "avg_watch_time_ms": 8421,
    "total_watch_time_ms": 1934000,
    "completion_rate": 0.29
  }
}
```

### YouTube video

YouTube populates all five watch fields via the Analytics API + Data API. `avg_watch_time_ms` is derived from `averageViewDuration` (seconds), `total_watch_time_ms` from `estimatedMinutesWatched`, `completion_rate` from `averageViewPercentage`, and `video_duration_ms` parsed from the video's ISO 8601 `contentDetails.duration`.

```json theme={null}
{
  "publish_id": "dQw4w9WgXcQ",
  "platform": "youtube",
  "type": "Video",
  "stats": {
    "likes": 318,
    "comment_count": 42,
    "views": 4271,
    "impressions": 4271,
    "video_duration_ms": 26500,
    "avg_watch_time_ms": 9100,
    "total_watch_time_ms": 2280000,
    "completion_rate": 0.342
  }
}
```

### LinkedIn video (ugcPost)

LinkedIn exposes `avg_watch_time_ms`, `total_watch_time_ms`, and `views` from the `/rest/videoAnalytics` endpoint. `completion_rate` and `video_duration_ms` are always `null` — LinkedIn doesn't surface them on this endpoint. Shape below reflects real data from a Marky LinkedIn post.

```json theme={null}
{
  "publish_id": "urn:li:ugcPost:7461905761766395905",
  "platform": "linkedin",
  "type": "Video",
  "stats": {
    "likes": 6,
    "comment_count": 0,
    "shares": 1,
    "impressions": 412,
    "views": 34,
    "video_duration_ms": null,
    "avg_watch_time_ms": 11519,
    "total_watch_time_ms": 391677,
    "completion_rate": null
  }
}
```

### X (Twitter) video

X exposes `completion_rate` derived from `non_public_metrics.playback_100_count / video_views` and `video_duration_ms` from the media object's `duration_ms`. `avg_watch_time_ms` and `total_watch_time_ms` are always `null` (X doesn't expose them directly).

```json theme={null}
{
  "publish_id": "1799123456789012345",
  "platform": "twitter",
  "type": "Video",
  "stats": {
    "likes": 14,
    "comment_count": 2,
    "shares": 3,
    "impressions": 5000,
    "views": 1000,
    "video_duration_ms": 32000,
    "avg_watch_time_ms": null,
    "total_watch_time_ms": null,
    "completion_rate": 0.31
  }
}
```

### Pinterest video Pin

Pinterest populates `avg_watch_time_ms` (from `VIDEO_AVG_WATCH_TIME`), `views` (from `VIDEO_MRC_VIEW`), and `completion_rate` (from `QUARTILE_95_PERCENT_VIEW / VIDEO_MRC_VIEW`). `total_watch_time_ms` and `video_duration_ms` are always `null` — not derivable from Pinterest's standard Pin endpoint. For image Pins, all watch fields are `null`.

```json theme={null}
{
  "publish_id": "670473463322902306",
  "platform": "pinterest",
  "type": "Video",
  "stats": {
    "impressions": 2840,
    "saves": 18,
    "clicks": 47,
    "views": 612,
    "video_duration_ms": null,
    "avg_watch_time_ms": 4180,
    "total_watch_time_ms": null,
    "completion_rate": 0.114
  }
}
```

### TikTok video

TikTok exposes `video_duration_ms` from the video's `duration` field. All other watch fields are always `null` (TikTok doesn't expose them).

```json theme={null}
{
  "publish_id": "7298765432109876543",
  "platform": "tiktok",
  "type": "Video",
  "stats": {
    "likes": 412,
    "comment_count": 23,
    "shares": 89,
    "views": 12450,
    "video_duration_ms": 28000,
    "avg_watch_time_ms": null,
    "total_watch_time_ms": null,
    "completion_rate": null
  }
}
```

## Example account-stat responses (demographics)

### Instagram

Real shape from a Marky-connected account. Age uses IG's native buckets, gender uses `F` / `M` / `U`, country uses ISO 3166-1 alpha-2 codes, city uses display strings.

```json theme={null}
{
  "platform": "instagram",
  "account_id": "17841405822304914",
  "followers": 1842,
  "audience_age_pct": {
    "13-17": 0.0036,
    "18-24": 0.1035,
    "25-34": 0.369,
    "35-44": 0.286,
    "45-54": 0.142,
    "55-64": 0.068,
    "65+": 0.028
  },
  "audience_gender_pct": {
    "F": 0.1884,
    "M": 0.6581,
    "U": 0.1535
  },
  "audience_country_pct": {
    "US": 0.412,
    "GB": 0.087,
    "BD": 0.0299,
    "DE": 0.0087,
    "RS": 0.0048
  },
  "audience_city_pct": {
    "London, England": 0.0336,
    "Sydney, New South Wales": 0.019,
    "Casablanca, Grand Casablanca": 0.0147
  }
}
```

### LinkedIn (organization page)

LinkedIn returns four demographic dimensions, all keyed by LinkedIn URNs. See "Platform-specific caveats" above for how to resolve URN keys to human-readable labels. Real shape from a Marky LinkedIn page.

```json theme={null}
{
  "platform": "linkedin",
  "account_id": "90535742",
  "page_id": "urn:li:organization:90535742",
  "followers": 412,
  "audience_country_pct": {
    "urn:li:geo:103644278": 0.5268,
    "urn:li:geo:102713980": 0.1111,
    "urn:li:geo:101165590": 0.0326
  },
  "audience_industry_pct": {
    "urn:li:industry:4": 0.1365,
    "urn:li:industry:1862": 0.0794,
    "urn:li:industry:96": 0.0672
  },
  "audience_seniority_pct": {
    "urn:li:seniority:3": 0.304,
    "urn:li:seniority:4": 0.2907,
    "urn:li:seniority:10": 0.1322
  },
  "audience_function_pct": {
    "urn:li:function:4": 0.2632,
    "urn:li:function:8": 0.1693,
    "urn:li:function:15": 0.1144
  }
}
```

### YouTube

YouTube uses its native bucket strings for age (`age13-17`, `age18-24`, etc.) and gender (`male`, `female`, `user_specified`, `gender_other`), and ISO codes for country.

```json theme={null}
{
  "platform": "youtube",
  "account_id": "UCabcdefghij",
  "followers": 5240,
  "audience_age_pct": {
    "age18-24": 0.181,
    "age25-34": 0.342,
    "age35-44": 0.244,
    "age45-54": 0.137,
    "age55-64": 0.062,
    "age65-": 0.034
  },
  "audience_gender_pct": {
    "male": 0.612,
    "female": 0.331,
    "user_specified": 0.057
  },
  "audience_country_pct": {
    "US": 0.487,
    "GB": 0.094,
    "CA": 0.061,
    "AU": 0.038
  }
}
```

### Pinterest

Demographic fields are defined on the schema but not yet populated by Marky's Pinterest integration — coming in a future release. Account-level engagement metrics (`followers`, `posts_count`) still populate.

```json theme={null}
{
  "platform": "pinterest",
  "account_id": "857294031829374821",
  "followers": 1247,
  "audience_age_pct": null,
  "audience_gender_pct": null,
  "audience_country_pct": null,
  "audience_city_pct": null,
  "audience_industry_pct": null,
  "audience_seniority_pct": null,
  "audience_function_pct": null
}
```

### X (Twitter)

X does not expose audience demographics for organic accounts. All seven demographic fields are always `null`.

```json theme={null}
{
  "platform": "twitter",
  "account_id": "1234567890",
  "followers": 384,
  "following": 412,
  "audience_age_pct": null,
  "audience_gender_pct": null,
  "audience_country_pct": null,
  "audience_city_pct": null,
  "audience_industry_pct": null,
  "audience_seniority_pct": null,
  "audience_function_pct": null
}
```

### TikTok

TikTok does not expose audience demographics through the Display API. All seven demographic fields are always `null`.

```json theme={null}
{
  "platform": "tiktok",
  "account_id": "7298765432109876543",
  "followers": 8421,
  "audience_age_pct": null,
  "audience_gender_pct": null,
  "audience_country_pct": null,
  "audience_city_pct": null,
  "audience_industry_pct": null,
  "audience_seniority_pct": null,
  "audience_function_pct": null
}
```
