---
title: "Response Schema"
description: "Account, Post, Comment, Group and Page — the types every SNS platform returns, field by field."
---

Five types cover every SNS operation, and a field means the same thing on every platform.

Optional fields are genuinely optional: **absent means the platform did not say**. An absent
`metrics.likes` is a hidden count, not zero likes. Times are ISO 8601, UTC. Every object carries
`platform`, and may carry `ext`: the facts only that platform has, under that platform's own names.

## Account

A person, creator, channel or page.

| Field | Type | Notes |
|---|---|---|
| `platform` | string | `reddit` `tiktok` `youtube` `instagram` `threads` `linkedin` `x` |
| `handle` | string | the @name, or the platform's equivalent |
| `url` | string | the profile page |
| `id` | string? | the platform's stable id |
| `displayName` `bio` | string? | |
| `avatarUrl` `bannerUrl` | string? | |
| `verified` | boolean? | |
| `createdAt` | string? | when the account was created |
| `counts` | object? | `{followers?, following?, posts?}` |
| `links` | array? | `{url, title?}` — the links on the profile |
| `private` | boolean? | a private or protected account: its posts are visible only to approved followers |
| `category` | string? | the account's own category label, verbatim (`Musician/Band`, `Media & News Company`) |
| `ext` | object? | platform-only facts |

## Post

A post, video, reel, short, thread or tweet.

| Field | Type | Notes |
|---|---|---|
| `id` `url` | string | |
| `author` | AccountRef | `{platform, id?, handle?, displayName?, url?, avatarUrl?, verified?, counts?}` |
| `title` | string? | where the platform has titles (Reddit, YouTube) |
| `text` | string? | the body or caption |
| `createdAt` `editedAt` | string? | |
| `lang` | string? | |
| `media` | Media[] | images, GIFs, videos and embeds — see below |
| `metrics` | object? | `{likes?, comments?, shares?, views?, reposts?, quotes?, saves?, liveViewers?}` |
| `entities` | object? | `{mentions?, urls?, hashtags?}` found in the text |
| `linkPreview` | object? | `{url, title?, description?, thumbnailUrl?, domain?}` |
| `poll` | object? | `{options: [{text, votes?}], totalVotes?, endsAt?}` |
| `place` | object? | `{name, id?, lat?, lng?, address?, city?, region?, postalCode?, country?}` |
| `audio` | object? | `{id?, title?, artist?, url?}` — a TikTok sound, a reel's audio |
| `live` | boolean? | a live stream |
| `broadcast` | object? | `{status, scheduledAt?, startedAt?, endedAt?}` — the stream's lifecycle; `status` is `scheduled`, `live` or `ended` |
| `repostOf` `quoteOf` | Post? | the post this one reposts or quotes |
| `inReplyTo` | object? | `{id, url?, author?}` — the post this one replies to |
| `sponsored` | boolean? | a paid or branded-content post |
| `pinned` | boolean? | pinned by its author to the top of their profile |
| `aiGenerated` | boolean? | the platform labels it AI-generated |
| `sensitive` | boolean? | the platform marks it sensitive or NSFW |
| `ext` | object? | platform-only facts |

What each platform counts as `views` differs: TikTok and YouTube report plays, X reports impressions.
Reddit's `score` is not likes, so it is in `ext`, never in `metrics.likes`. `shares` counts shares and sends
only: `reposts` and `quotes` have their own counts, and `saves` is bookmarks. `liveViewers` is the audience
watching right now, so it appears only while `broadcast.status` is `live`.

The `true`/`false` flags (`sponsored`, `pinned`, `aiGenerated`, `sensitive`, `byAuthor`, …) follow the same rule
as counts: absent means the platform did not say.

### Media

| Field | Type | Notes |
|---|---|---|
| `type` | `image` \| `gif` \| `video` \| `embed` | |
| `url` | string | |
| `width` `height` | number? | |
| `thumbnailUrl` | string? | |
| `durationSec` | number? | |
| `variants` | array? | other renditions: `{url, width?, height?, bitrate?, contentType?}` |
| `altText` `caption` | string? | |

## Comment

| Field | Type | Notes |
|---|---|---|
| `id` `postId` | string | |
| `parentId` | string? | the comment this one replies to |
| `author` | AccountRef | |
| `text` | string | |
| `createdAt` `editedAt` `lang` | string? | |
| `pinned` | boolean? | |
| `byAuthor` | boolean? | written by the post's author |
| `likedByAuthor` | boolean? | the post's author liked or hearted it |
| `metrics` | object? | `{likes?, replies?}` |
| `media` | Media[]? | |
| `replies` | Comment[] | replies included with this comment |
| `moreReplies` | object? | `{count?, ids?, cursor?}` — what was left unloaded; load it with `comments`: `comment=` the cursor (YouTube) or the comment's `id` (Reddit, TikTok), or Reddit's `ids` |

## Group

Anything posts gather under.

| Field | Type | Notes |
|---|---|---|
| `kind` | string | `community` `channel` `company` `hashtag` `sound` `topic` `location` `list` |
| `id` `name` `url` | string | |
| `description` | string? | |
| `avatarUrl` `bannerUrl` | string? | |
| `createdAt` | string? | |
| `counts` | object? | `{members?, posts?}` |
| `sensitive` | boolean? | the platform marks the group sensitive or NSFW |

## Page

Every list.

```json
{ "platform": "tiktok", "items": [ /* Post, Comment, Account or Group */ ], "cursor": "…", "total": 1640 }
```

Call the same operation with `cursor` alone for the next page. No `cursor` means this is the last page.

`total`, when present, is how many items the whole list holds, exactly as the platform states it. It is omitted
when the platform gives no exact count. It is not a promise that every item is reachable: platforms cap how
far a list pages, and the list ends when the `cursor` does.

A comment page can also carry `ext.post` (the post the comments are on) and `ext.more` (top-level comments the platform left unloaded) — Reddit returns both.
