InsightSocial API
Unified schema

Post

The schema-2 post object. Every field, its type, and which platforms fill it.

Any endpoint that returns a post returns it in this shape, whichever platform it came from. Write one parser and it reads posts from every platform the API serves. This page describes schema 2, which every key gets from October 4, 2026. What changed from the previous shape is on Schema 2.

Where posts sit in data

Endpoint returnsPath
One post (/v1/instagram/post, /v1/youtube/video, …)data.post
A list of posts (/v1/instagram/profile/posts, /v1/tiktok/search, …)data.items[].post

A list also carries data.total, the total the platform states (not the size of this page), and data.truncated, true when the platform cut the list short. Both are null when the platform does not say. The next page is in pagination.next_cursor; see Pagination.

Example

One row from /v1/instagram/profile/posts?handle=nasa, shortened:

Response
{
  "success": true,
  "platform": "instagram",
  "endpoint": "/v1/instagram/profile/posts",
  "schema_version": "2",
  "data": {
    "items": [
      {
        "post": {
          "id": "3983374110243288826",
          "url": "https://www.instagram.com/nasa/p/DdHyaYAifb6/",
          "kind": "carousel",
          "content": {
            "text": "Cementing their names in history. …",
            "media_urls": ["https://scontent-lga3-2.cdninstagram.com/v/…", "https://scontent-lga3-3.cdninstagram.com/v/…"],
            "thumbnail_url": null,
            "duration_seconds": null
          },
          "author": {
            "id": "528817151",
            "username": "nasa",
            "display_name": "NASA",
            "avatar_url": "https://scontent-lga3-1.cdninstagram.com/v/…",
            "verified": true
          },
          "engagement": { "views": null, "likes": 120041, "comments": 978, "shares": null, "saves": null },
          "flags": {
            "nsfw": null, "spoiler": null, "pinned": true, "deleted": false,
            "likes_hidden": null, "comments_hidden": null, "shares_hidden": null,
            "views_hidden": null, "saves_hidden": null
          },
          "published_at": "2026-09-10T21:20:24.000Z",
          "language": null,
          "ext": { "media_type": "carousel", "carousel_count": 4 }
        }
      }
    ],
    "total": null,
    "truncated": null
  },
  "pagination": { "next_cursor": "v2c.ZIyWbi3x…", "has_more": true, "page_size": 12 },
  "unavailable": [],
  "credits_used": 10,
  "credits_remaining": 9990,
  "request_id": "req_bc4ed40ba570",
  "cached": false,
  "idempotent_replay": false,
  "charge_reason": "miss",
  "free_call": false
}

Fields

Every field below is always present. A value the platform does not give is null, never left out and never a placeholder.

FieldTypeNullableDescription
idstringNoThe platform's ID for the post. Always a string. Never parse it as a number: Instagram and X IDs are larger than 2^53.
urlstringYesLink to the post on the platform.
kindstringYesThe post's format: text, image, carousel, video, short, live, article or link. short is short-form vertical video (a reel, a TikTok, a YouTube Short). null when the platform does not say and it cannot be read without guessing. More values may be added, so keep a default branch when you switch on it.
content.textstringYesCaption, description or body text.
content.media_urlsstring[]YesMain media, always an array, one URL per item, even for a single photo. null when the platform gives none.
content.thumbnail_urlstringYesThumbnail image.
content.duration_secondsnumberYesLength of a video or clip in seconds. null when the post is not a video.
author.idstringYesThe author's platform ID. On Reddit it is the account's t2_… ID, prefix kept. On LinkedIn a person's member URN (ACoAA…), as on their profile, with the numeric member id in ext.author_member_id; a company's numeric id. null where the source gives none; see Which platforms fill which fields.
author.usernamestringYesThe author's handle.
author.display_namestringYesThe author's display name. On Reddit usually null: Reddit shows a username, and the t2_… ID that arrives in this place goes to author.id.
author.avatar_urlstringYesThe author's profile picture.
author.verifiedbooleanYesWhether the author is verified.
engagement.viewsintegerYesViews where the platform shows them. On Instagram videos and reels this is the play count shown in the app, and it counts Instagram plays only, not views of a copy cross-posted to Facebook. Fetch the Facebook copy with /v1/facebook/post if you need both.
engagement.likesintegerYesLikes or reactions. On Reddit a score below zero is not a like count: likes is null and the score is in ext.score.
engagement.commentsintegerYesComment count. On /v1/instagram/post it counts top-level comments; the Instagram list endpoints count all comments including replies. Both use this field.
engagement.sharesintegerYesShares, reposts or retweets. On Instagram this is the Send count, available only from /v1/instagram/post/stats, /v1/instagram/profile/reels/full and /v1/instagram/profile/posts/full; other Instagram endpoints return null.
engagement.savesintegerYesSaves or bookmarks.
flags.nsfwbooleanYesMarked as adult content. null when the platform does not say.
flags.spoilerbooleanYesMarked as a spoiler. null when the platform does not say.
flags.pinnedbooleanYesPinned to the profile. null when the platform does not say.
flags.deletedbooleanNoThe post has been deleted or removed. Always true or false.
flags.likes_hiddenbooleanYestrue when the creator hides the like count; engagement.likes is then null. null on ordinary posts.
flags.comments_hiddenbooleanYestrue when the comment count is hidden; engagement.comments is then null.
flags.shares_hiddenbooleanYestrue when the share count is hidden; engagement.shares is then null.
flags.views_hiddenbooleanYestrue when the view count is hidden; engagement.views is then null.
flags.saves_hiddenbooleanYestrue when the save count is hidden; engagement.saves is then null.
published_atstringYesWhen the post was published, as ISO 8601 in UTC, ending in Z. Platforms that send Unix timestamps are converted.
languagestringYesThe post's language as the platform itself states it, such as en or pt-BR. null when the platform gives no tag. We do not detect languages.
extobjectYesPlatform-specific fields. See below.

Counts: null is not 0

A count is a whole number of zero or more, or null. null means the platform does not show it, or hides it on this post. 0 means it really is zero. Do not add a null into a total as if it were zero.

Extension fields (ext)

Platform-specific extras. Each one appears only on platforms that provide it and is left out elsewhere, so treat all of them as optional. They hold detail the unified fields cannot, and the IDs that let you pass a result from one endpoint into the next. ext is null when a post has no extras.

Keys are always snake_case, on every platform, YouTube included (made_for_kids, category_id). An ext value whose key ends in _id is a string, and one whose key ends in _at is an ISO 8601 UTC time. ext never carries our cursors or tokens; page with pagination.next_cursor.

FieldTypeNullableDescription
ext.music_idstringYesTikTok sound ID. Pass it to /v1/tiktok/song/videos?clipId= to find other videos using the same sound.
ext.author_followersintegerYesThe author's follower count as carried on the row: X and TikTok post rows, and searches that include it. A snapshot, not live. Always null on Instagram rows; call /v1/instagram/profile?handle= for the exact current count.
ext.author_followingintegerYesFollowing count included in the row, when present.
ext.author_posts_countintegerYesThe author's post count included in the row, when present.
ext.download_countintegerYesTikTok only. How many times the video was downloaded to a device. Separate from engagement.saves, which counts saves to an in-app collection.
ext.regionstringYesTikTok only. The ISO 3166-1 alpha-2 country the video is registered to, usually the creator's account country. It is not the viewer's country or a language. On /v1/tiktok/trending, /v1/tiktok/search and /v1/tiktok/search/top, filter on it to keep rows from one country.
ext.subredditstringYesReddit subreddit name on search and list rows. Pass it to /v1/reddit/subreddit/details?subreddit=.
ext.titlestringYesPost title, where the platform separates title from body.
ext.selftextstringYesReddit text-post body.
ext.upvote_ratiointegerYesReddit only. Share of votes that are upvotes, from 0 to 1. The value is a fraction even though the type says integer. Filled on /v1/reddit/search rows where available, null elsewhere.
ext.flairstringYesReddit post flair.
ext.typestringYesPlatform's own post type.
ext.content_typestringYesPlatform's own content type. kind is read from it where it is present.
ext.video_view_countintegerYesInstagram's old 3-second view count. No longer served, so new lookups do not carry it. Use engagement.views.
ext.ig_play_countintegerYesInstagram's own play count, shown separately so you can tell it apart from any combined figure. Present on /v1/instagram/post/stats, and on /v1/instagram/post for videos.
ext.repost_countintegerYesRepost count, where it is separate from shares.
ext.media_typestringYesPlatform's media type (photo, video, carousel and so on). kind is read from it where it is present.
ext.text_truncatedbooleanYestrue when the text was cut short on this surface.
ext.ip_locationstringYesLocation the platform displays for the poster, where shown.
ext.carousel_countintegerYesNumber of items in a carousel.
ext.remix_countintegerYesNumber of remixes.
ext.facebook_likesintegerYesInstagram only. Facebook likes from a cross-post that were removed from engagement.likes, so that field matches what instagram.com shows. Add them back for a combined figure. Absent when nothing was removed or the like count is hidden.
ext.facebook_commentsintegerYesInstagram only. The comment equivalent of ext.facebook_likes. Each of the two appears only for the count it changed.
ext.usertagsstring[]YesAccounts tagged in the post.
ext.coauthorsstring[]YesInstagram Collab posts. Every co-author as { id, username, full_name, is_verified, profile_pic_url }. A Collab post has one creator but shows on every co-author's grid, so post.author may not be the profile you asked for. All accounts on the post are post.author.username plus each username here. An empty array means not a Collab. Absent where there is no signal, including on /v1/instagram/post; use /v1/instagram/post/stats for a single post.
ext.musicstringYesMusic or sound attached to the post.
ext.sponsor_tagsstring[]YesSponsor or paid-partnership tags.
ext.locationstringYesLocation tagged on the post.
ext.quoted_poststringYesThreads quote posts. The quoted post as { id, url, author: { id, username }, text, media_urls, thumbnail_url }. A quote post often has no text or media of its own, and what you see on its page belongs to the quoted post by another author. It stays here so content.* always describes the outer post. Absent on posts that are not quotes.
ext.retweeted_poststringYesTwitter/X: the original post behind a retweet.
ext.quote_countintegerYesNumber of quote posts.
ext.all_media_urlsstring[]YesEvery media URL on the post.
ext.reaction_countsstring[]YesCounts broken down by reaction type.
ext.share_urnstringYesLinkedIn share URN.
ext.post_typestringYesPlatform's post type.
ext.activity_idstringYesLinkedIn activity ID.
ext.published_at_precisionstringYesHow precise published_at is when the platform shows only a relative or rounded time.
ext.author_urnstringYesLinkedIn URN of the author.
ext.author_headlinestringYesLinkedIn headline of the author.
ext.author_typestringYesWhether the LinkedIn author is a person or a company.
ext.is_repost_quotebooleanYestrue when a repost adds its own commentary.
ext.articlestringYesLinkedIn article attached to the post.
ext.reaction_typestringYesThe reaction a member left, on reaction lists.
ext.download_media_urlsstring[]YesDownloadable media URLs, when requested.
ext.tagsstring[]YesTags attached to the post.
ext.category_idstringYesYouTube category ID.
ext.category_titlestringYesYouTube category name.
ext.topic_categoriesstring[]YesYouTube topic categories.
ext.durationstringYesYouTube duration in its original format.
ext.licensestringYesYouTube license.
ext.made_for_kidsbooleanYesYouTube made-for-kids flag.
ext.default_audio_languagestringYesYouTube default audio language.
ext.has_paid_product_placementbooleanYesYouTube paid product placement flag.
ext.captionstringYesYouTube caption status.
ext.positionintegerYesPosition in a YouTube playlist.
ext.playlist_idstringYesYouTube playlist ID.
ext.video_owner_channel_idstringYesChannel that owns a video in a playlist.
ext.video_published_atstringYesWhen a playlist video was published.
ext.descriptionstringYesFull description, where separate from content.text.
ext.playlist_item_idstringYesYouTube playlist item ID.
ext.playlist_owner_channel_idstringYesChannel that owns the playlist.
ext.playlist_owner_titlestringYesName of the playlist owner.
ext.published_labelstringYesThe relative time label the platform shows, such as "3 days ago".
ext.published_precisionstringYesHow precise the published time is.
ext.video_countintegerYesNumber of videos, on playlist or collection rows.
ext.commercestringYesShopping or commerce details attached to the post.
ext.on_screen_textsstring[]YesText shown on screen in the video.
ext.topic_tagstringYesThreads topic tag.
ext.topic_tag_idstringYesThreads topic tag ID.
ext.reshare_countintegerYesReshare count, where reported separately.
ext.adstringYesFacebook Ad Library details, on /v1/facebook/adlibrary/ad and /v1/facebook/adlibrary/company/ads rows: page_id, currency, spend, reach_estimate, publisher_platforms, categories, targeted_or_reached_countries, cta_text, cta_type, link_url, is_active, end_date_iso, display_format, title, video_hd_url, video_sd_url. Absent elsewhere.
ext.feedback_idstringYesFacebook feedback ID, used to fetch comments and replies.
ext.eventstringYesFacebook event details, including interested_count, going_count, end_timestamp and ticket_url.
ext.trendstringYesTikTok trend-board data. On /v1/tiktok/hashtags/popular: rank, country_code, period_days, posts and views for the period (not lifetime), industry, industry_id, industry_label for the first board read (null for the overall board), boards listing every board the hashtag ranks on as { industry, industry_id, industry_label, rank }, popularity_curve as { date, value } with value 0 to 100 relative to the period's peak, and top_creators. On /v1/tiktok/videos/popular: rank, country_code, period_days, order_by, period_views, organic_views, engagement_rate, six_second_view_through_rate, content_tags. Absent elsewhere.
ext.updated_atstringYesWhen the post was last edited, where shown.
ext.scoreintegerYesReddit only. A post score below zero. A negative score is not a like count, so engagement.likes is null and the score is kept here. Absent when the score is zero or above.

Which platforms fill which fields

Every platform returns this shape. id and flags.deleted are never null. The table covers the nine platforms the API launched with. The others return the same shape, and each response's unavailable list names the fields it could not fill. How to read the table: yes marks a field the platform is able to supply, though any single row can still have it null. An empty cell marks a field that platform never supplies, so expect null every time.

Platformauthor.verifiedengagement.savesengagement.sharescontent.duration_secondsengagement.viewsauthor.avatar_urlengagement.commentscontent.media_urlsurlengagement.likescontent.thumbnail_urlflags.pinned
Facebookyesyesyesyesyesyesyesyesyesyes
Instagramyesyesyesyesyesyesyesyesyesyesyes
LinkedInyesyesyesyesyesyesyesyes
Pinterestyesyesyesyesyesyesyesyesyesyes
Reddityesyesyesyesyesyesyesyes
Threadsyesyesyesyesyesyesyesyesyes
TikTokyesyesyesyesyesyesyesyesyesyesyesyes
Twitter/Xyesyesyesyesyesyesyesyesyesyesyes
YouTubeyesyesyesyesyesyesyesyes

Instagram saves come only from /v1/instagram/post/stats with include=saves. See Metric substitutions for the full list of per-platform nulls.

The three fields schema 2 added are filled where the platform gives them:

  • author.id: Facebook, Instagram list endpoints, LinkedIn, TikTok, YouTube (the channel ID) and Reddit, where it is the account's t2_… ID with the prefix kept, the same value comments and profiles carry. On Threads, Twitter/X and Pinterest the source usually gives none, so it is null and the response lists it in unavailable.
  • kind: read from the platform's own media or content type where it sends one (Instagram, YouTube), and otherwise only where the format is certain: a reel or Shorts URL, a TikTok video, a LinkedIn article. null otherwise.
  • language: only where the platform tags it, such as YouTube, Reddit and Twitter/X.

unavailable

When a field the platform normally fills is null on every post in a response, the response lists its path in unavailable, for example "items[].post.author.id". One filled row is enough to keep a field off the list. Fields a platform never shows publicly are never listed, so you are not told on every call:

PlatformNever listed in unavailable
Instagramengagement.shares, engagement.saves
Facebookauthor.username, engagement.saves
Threadsengagement.saves
YouTubeengagement.shares, engagement.saves
Redditengagement.views, engagement.shares, engagement.saves, author.display_name
LinkedInengagement.views, engagement.saves
Pinterestengagement.views

Instagram shares and saves are on the list because only the endpoints named above fill them; a plain Instagram post leaves them null without that being a gap. TikTok and Twitter/X have nothing on the list. kind, content.* and language are never listed on any platform, because null there usually describes the post (a photo has no duration) rather than a missing field.

More on this in Data availability.

Returned by

Endpoints that return a post or a list of posts use this shape on:

Facebook · Instagram · LinkedIn · Pinterest · Reddit · Threads · TikTok · Twitter/X · YouTube

To see which native platform field feeds each unified field, read Field equivalence.

On this page