Get one post or reel in full
One Instagram post or reel in full: caption, date, like, comment and play counts, every carousel frame and rendition, tagged accounts and places, and a preview of its comments. Pass its URL, short code or id; add include for repost, share and save counts.
/post-detail Posts & reels https://api.fetchlayer.dev/instagram/post-detail Headers
Authorization string required Bearer token — your FetchLayer API key.
Parameters
post string required A post or reel URL — /p/<code>/, /reel/<code>/, /reels/<code>/, /tv/<code>/, or Instagram’s own /<username>/p/<code>/ and /<username>/reel/<code>/ forms — the short code from that URL, or the post’s numeric id (the id any response returns, with or without its _<owner id> suffix).
include string[] optional Optional extra counts: any of "reposts", "shares" and "saves". "reposts" fills repostCount on every kind of post; "shares" and "saves" fill shareCount and saveCount on reels and videos (photos and carousels have none). It adds about 1 to 2 seconds. On the rare request where a count is temporarily unavailable it is null with a note asking you to retry. The price is unchanged: 1 credit per page fetched. Without include the three are null and the note says so. Any other value is a 400; "country" belongs to user-profile.
format string optional json or markdown, lowercase; any other value is a 400. Over MCP, markdown returns the result rendered as text; the REST API accepts it and returns JSON. (default: json)
timeoutMs integer optional Time limit for the whole request, in milliseconds (1000–120000); a value outside that range is a 400. When it runs out, a paged request returns what it has with nextCursor, billed for the pages it returned; a request with nothing to return yet fails with a 503 you can retry, marked with the response header X-Timeout-Source: caller. Left out, the request runs as long as it needs. A video or reel takes about a second longer than a photo, around four at the slow end.
Response Fields
post-detail
Get one post or reel in full
transport string The data source: always the platform id, "instagram".
notes string[] Caveats you can act on — a ceiling Instagram imposes, a counter it withholds, a list that stopped early. Several real limits are reported only here, so read them. An empty result always comes with a note explaining it, never as an unexplained empty array.
pagesFetched number Pages of results fetched, which is what the request costs: one credit per page. resolve-url reports 0 and is not billed.
post object The post or reel, in the shape below.
post.id string Instagram’s exact media id, as a string: it is a 64-bit number, larger than a JSON number can carry exactly, so keep it as a string. post-detail and post-comments accept it as post.
post.shortcode string The code in the post URL. post-detail and post-comments both accept it.
post.url string Canonical link to the post or reel.
post.kind string image, video or carousel.
post.productType string | null What Instagram calls the surface — "feed" for a grid post, "clips" for a reel — or null.
post.caption string | null The author’s own written post body, or null. This is a caption, not a transcript: Instagram publishes no transcript of spoken audio.
post.createdAt string | null ISO 8601 timestamp, or null: always null on reels-feed, and null on a listing record whose fieldsFrom is "listing".
post.likeCount integer | null Likes, or null: always null on reels-feed, null on a listing record whose fieldsFrom is "listing", and absent when countsHidden is true.
post.commentCount integer | null Comments, or null in the same cases as likeCount.
post.playCount integer | null Instagram plays on a video or reel: the view count Instagram shows on it, the same figure on listings and on post-detail (plays on Facebook are not included). Null for photos and carousels, whose views Instagram does not make public, and for posts from a restricted account. On post-detail it can occasionally be null for a video; the note says so, and a retry usually returns it.
post.videoDuration number | null Length of a video or reel in seconds, with decimals. Null for a photo or carousel (each carousel frame carries its own carousel[].videoDuration), on reels-feed, and on a listing record whose fieldsFrom is "listing".
post.shareCount integer | null How many times the post was shared, as Instagram counts it under a reel. Filled when include lists "shares" (post-detail, user-posts, user-reels); reels and videos only, null on photos and carousels. Also null — not 0 — when the account hides it, and the note says so.
post.repostCount integer | null How many times the post was reposted to other accounts’ profiles. Filled when include lists "reposts" (post-detail, user-posts, user-reels); every kind of post.
post.saveCount integer | null How many times the post was saved. Filled when include lists "saves" (post-detail, user-posts, user-reels); reels and videos only, null on photos and carousels.
post.countsHidden boolean | null True when the account has turned like and view counts off. The counts are then absent rather than zero.
post.width integer | null Pixel width, or null where the record does not carry it.
post.height integer | null Pixel height, or null where the record does not carry it.
post.altText string | null Instagram’s own auto-generated image description ("Photo by NASA on August 19, 2026. May be an image of text."), or null. Machine-written alt text, not a caption and not a transcript.
post.thumbnailUrl string | null Preview frame, or null.
post.assets object[] Ordered and de-duplicated renditions, each with kind, url, width, height and downloadUrl.
post.assets[].downloadUrl string | null Pass it to GET /media to stream the bytes. Instagram’s own links are signed and expire; this one keeps working.
post.carousel object[] One entry per frame of a carousel, each with its own renditions and, for a video frame, its own videoDuration. Empty for a single image or video.
post.author object id, username, fullName, profilePicUrl, verified, privateAccount and profileUrl. Fields Instagram does not publish on a listing are null.
post.coauthors object[] Accounts credited as co-authors of a collab post.
post.taggedUsers object[] Accounts tagged in the image.
post.location object | null The place the post was tagged at, or null.
post.hashtags string[] Without the #.
post.mentions string[] Usernames without the @.
post.topics string[] Instagram’s own subject labels for the post ("jwst", "star birth"), where it publishes them.
post.hasAudio boolean | null Whether the video carries audio, or null.
post.fieldsFrom string Which shape this record has, so a null count is never mistaken for a zero. "detail" is a full post, from post-detail. "listing_full" is a listing record with its posting date and counts, which is what user-posts and user-reels return. "listing" is a record without them: every reel on reels-feed, and on user-posts or user-reels only a post that is named in the note by short code, with the fields it lacks. Asking again with include returns them, and so does post-detail.
post.audio object | null The sound on a video or reel, where Instagram publishes it with the post; null otherwise. Ids are exact strings.
post.audio.type string | null Instagram’s label for the sound, e.g. original_sounds or licensed_music.
post.audio.originalSoundTitle string | null The title of an original sound, e.g. Original audio.
post.audio.artistUsername string | null The account an original sound is credited to.
post.audio.durationMs integer | null Length of the sound in milliseconds.
post.audio.audioAssetId string | null The sound’s own id.
post.audio.canonicalId string | null The id Instagram groups uses of the same sound under.
post.audio.songTitle string | null Licensed music: the song’s title. Null for an original sound, or a song Instagram no longer makes available.
post.audio.songArtist string | null Licensed music: the artist as Instagram shows it.
post.audio.isExplicit boolean | null Licensed music: whether Instagram marks the song explicit. Null when there are no song details.
post.audio.audioClusterId string | null Licensed music: the id Instagram groups every use of the song under.
post.fullId string | null Instagram’s full id for the post, <id>_<author id>. Null when the author’s id is not known.
post.videoDownloadUrl string | null The first video’s downloadUrl, for GET /media, valid as long as its own link. Null for a photo, or when this response has no video link for the post.
post.thumbnailDownloadUrl string | null thumbnailUrl as a downloadUrl for GET /media, valid as long as thumbnailUrl is.
post.brandedContent object The paid-partnership label, and how far the accounts a post names are known in this response. Each status is found (present), not-published (Instagram shows none) or not-looked-up (not known in this response — never a statement that there is none). Sponsor accounts are not returned.
post.brandedContent.isPaidPartnership boolean | null Instagram’s paid-partnership label. Null when not known in this response.
post.brandedContent.paidPartnershipStatus string found, not-published or not-looked-up, for isPaidPartnership.
post.brandedContent.coauthorsStatus string found, not-published or not-looked-up, for coauthors.
post.brandedContent.taggedUsersStatus string found, not-published or not-looked-up, for taggedUsers.
post.brandedContent.captionTagsStatus string found, not-published or not-looked-up, for hashtags and mentions, which come from the caption and carry no account ids.
comments object[] A preview: the first comments on the post, about a dozen, without reply counts — replyCount is null on each. The note says how many; post-comments returns them all with their reply counts.
Request
curl -X POST "https://api.fetchlayer.dev/instagram/post-detail" \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"post":"https://www.instagram.com/p/DcOX3hWFiey/","include":["reposts","shares","saves"]}'Response
{
"transport": "instagram",
"notes": [
"Instagram does not publish view counts for photos and carousels publicly, so playCount is empty.",
"Instagram does not show share or save counts for photos and carousels, so shareCount and saveCount are empty.",
"This response includes the first 12 comments, without reply counts; use post-comments to read them all with their reply counts."
],
"pagesFetched": 1,
"post": {
"id": "3967213292204992434",
"shortcode": "DcOX3hWFiey",
"url": "https://www.instagram.com/p/DcOX3hWFiey/",
"kind": "image",
"productType": "feed",
"caption": "With your powers combined…\n\nThis colorful picture of the cosmos is the product of teamwork between our @NASAHubble, @NASAWebb, and @NASAChandraXray telescopes. …",
"createdAt": "2026-08-19T14:11:47.000Z",
"likeCount": 573281,
"commentCount": 4349,
"playCount": null,
"videoDuration": null,
"shareCount": null,
"repostCount": 14650,
"saveCount": null,
"countsHidden": false,
"width": 1280,
"height": 1129,
"altText": "Photo by NASA on August 19, 2026. May be an image of text.",
"thumbnailUrl": "https://scontent-dus1-1.cdninstagram.com/v/t51.82787-15/...",
"assets": [
{
"kind": "image",
"url": "https://scontent-dus1-1.cdninstagram.com/v/t51.82787-15/...",
"width": 1280,
"height": 1129,
"downloadUrl": "https://api.fetchlayer.dev/instagram/media?url=..."
}
],
"carousel": [],
"author": {
"id": "528817151",
"username": "nasa",
"fullName": "NASA",
"profilePicUrl": "https://scontent-dus1-1.cdninstagram.com/v/t51.2885-19/...",
"verified": true,
"privateAccount": false,
"profileUrl": "https://www.instagram.com/nasa/"
},
"coauthors": [],
"taggedUsers": [],
"location": null,
"hashtags": [
"nasa",
"universe",
"nebula"
],
"mentions": [
"nasahubble",
"nasawebb",
"nasachandraxray"
],
"topics": [
"carina nebula",
"jwst",
"star birth",
"cosmic clouds",
"astronomy photography",
"interstellar dust"
],
"hasAudio": null,
"fieldsFrom": "detail"
},
"comments": [
{
"id": "18041736590218845",
"text": "The colours in this one are unreal 🔭",
"createdAt": "2026-09-16T17:16:25.000Z",
"likeCount": 2,
"replyCount": null,
"author": {
"id": "61873402291",
"username": "example.stargazer",
"fullName": null,
"profilePicUrl": "https://scontent-dus1-1.cdninstagram.com/v/t51.82787-19/...",
"verified": false,
"privateAccount": null,
"profileUrl": "https://www.instagram.com/example.stargazer/"
}
}
]
}