Browse popular reels
Reels Instagram currently lists as popular, from many accounts, each with its play count, caption, author and video. No account or keyword needed, and which reels come back varies between calls. Paged: 12 reels per page, 1 credit per page fetched.
/reels-feed Discovery https://api.fetchlayer.dev/instagram/reels-feed Headers
Authorization string required Bearer token — your FetchLayer API key.
Parameters
limit integer optional Maximum items returned, up to 240. Use -1 for the maximum. Without it, every item on the pages fetched comes back, 12 a page (pages: 2 alone returns 24). A limit takes as many pages as it needs: a limit of 60 takes five pages and costs five credits. (default: every item on the pages fetched, 12 a page)
pages integer optional Pages of results to return in one request, up to 20. Use -1 for the maximum. Instagram serves 12 items per page and each page fetched is 1 credit, so a call costs the pages it fetches — set by pages, or by how many pages a limit needs — not the number of items returned. The response reports them as pagesFetched. (default: 1)
cursor string optional Continue from a previous response’s nextCursor. Send it back to reels-feed, which produced it; a cursor from another route, or a malformed one, is a 400.
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.
Response Fields
reels-feed
Browse popular reels
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.
posts object[] Reels Instagram currently lists as popular, each with playCount, caption, author and video links. Not a personalised or real-time feed. likeCount, commentCount and createdAt are null — post-detail returns a reel’s counts and date, user-reels a given account’s reels — and so are repostCount, shareCount and saveCount, as this route takes no include. If Instagram is listing no popular reels at that moment, the route answers 503; retry later.
posts[].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.
posts[].shortcode string The code in the post URL. post-detail and post-comments both accept it.
posts[].url string Canonical link to the post or reel.
posts[].kind string image, video or carousel.
posts[].productType string | null What Instagram calls the surface — "feed" for a grid post, "clips" for a reel — or null.
posts[].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.
posts[].createdAt string | null ISO 8601 timestamp, or null: always null on reels-feed, and null on a listing record whose fieldsFrom is "listing".
posts[].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.
posts[].commentCount integer | null Comments, or null in the same cases as likeCount.
posts[].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.
posts[].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".
posts[].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.
posts[].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.
posts[].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.
posts[].countsHidden boolean | null True when the account has turned like and view counts off. The counts are then absent rather than zero.
posts[].width integer | null Pixel width, or null where the record does not carry it.
posts[].height integer | null Pixel height, or null where the record does not carry it.
posts[].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.
posts[].thumbnailUrl string | null Preview frame, or null.
posts[].assets object[] Ordered and de-duplicated renditions, each with kind, url, width, height and downloadUrl.
posts[].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.
posts[].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.
posts[].author object id, username, fullName, profilePicUrl, verified, privateAccount and profileUrl. Fields Instagram does not publish on a listing are null.
posts[].coauthors object[] Accounts credited as co-authors of a collab post.
posts[].taggedUsers object[] Accounts tagged in the image.
posts[].location object | null The place the post was tagged at, or null.
posts[].hashtags string[] Without the #.
posts[].mentions string[] Usernames without the @.
posts[].topics string[] Instagram’s own subject labels for the post ("jwst", "star birth"), where it publishes them.
posts[].hasAudio boolean | null Whether the video carries audio, or null.
posts[].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.
posts[].audio object | null The sound on a video or reel, where Instagram publishes it with the post; null otherwise. Ids are exact strings.
posts[].audio.type string | null Instagram’s label for the sound, e.g. original_sounds or licensed_music.
posts[].audio.originalSoundTitle string | null The title of an original sound, e.g. Original audio.
posts[].audio.artistUsername string | null The account an original sound is credited to.
posts[].audio.durationMs integer | null Length of the sound in milliseconds.
posts[].audio.audioAssetId string | null The sound’s own id.
posts[].audio.canonicalId string | null The id Instagram groups uses of the same sound under.
posts[].audio.songTitle string | null Licensed music: the song’s title. Null for an original sound, or a song Instagram no longer makes available.
posts[].audio.songArtist string | null Licensed music: the artist as Instagram shows it.
posts[].audio.isExplicit boolean | null Licensed music: whether Instagram marks the song explicit. Null when there are no song details.
posts[].audio.audioClusterId string | null Licensed music: the id Instagram groups every use of the song under.
posts[].fullId string | null Instagram’s full id for the post, <id>_<author id>. Null when the author’s id is not known.
posts[].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.
posts[].thumbnailDownloadUrl string | null thumbnailUrl as a downloadUrl for GET /media, valid as long as thumbnailUrl is.
posts[].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.
posts[].brandedContent.isPaidPartnership boolean | null Instagram’s paid-partnership label. Null when not known in this response.
posts[].brandedContent.paidPartnershipStatus string found, not-published or not-looked-up, for isPaidPartnership.
posts[].brandedContent.coauthorsStatus string found, not-published or not-looked-up, for coauthors.
posts[].brandedContent.taggedUsersStatus string found, not-published or not-looked-up, for taggedUsers.
posts[].brandedContent.captionTagsStatus string found, not-published or not-looked-up, for hashtags and mentions, which come from the caption and carry no account ids.
postCount number How many items are in this response.
hasMore boolean Whether more results exist beyond what was returned.
nextCursor string | null Opaque value to pass back as cursor, to the same route (and the same account on an account listing), to continue. null when there is nothing further.
Request
curl -X POST "https://api.fetchlayer.dev/instagram/reels-feed" \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"limit":12}'Response
{
"transport": "instagram",
"notes": [
"Reels here are those Instagram currently lists as popular, from many accounts. They carry play counts, captions and media but no like counts, comment counts or posting dates; read a single post for those.",
"More results are available. Continue with nextCursor."
],
"pagesFetched": 1,
"posts": [
{
"id": "3809847048594935553",
"shortcode": "DTfS7SMEk8B",
"url": "https://www.instagram.com/reel/DTfS7SMEk8B/",
"kind": "video",
"productType": null,
"caption": "Four seasons in one valley. Which month would you pick? 🏔️\n\n#travel #switzerland #nature",
"createdAt": null,
"likeCount": null,
"commentCount": null,
"playCount": 30214234,
"videoDuration": null,
"shareCount": null,
"repostCount": null,
"saveCount": null,
"countsHidden": null,
"width": null,
"height": null,
"altText": null,
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.71878-15/...",
"assets": [
{
"kind": "video",
"url": "https://scontent.cdninstagram.com/o1/v/t2/f2/m86/...",
"width": null,
"height": null,
"downloadUrl": "https://api.fetchlayer.dev/instagram/media?url=..."
}
],
"carousel": [],
"author": {
"id": "787132",
"username": "natgeo",
"fullName": null,
"profilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/...",
"verified": true,
"privateAccount": null,
"profileUrl": "https://www.instagram.com/natgeo/"
},
"coauthors": [],
"taggedUsers": [],
"location": null,
"hashtags": [
"travel",
"switzerland",
"nature"
],
"mentions": [],
"topics": [],
"hasAudio": null,
"fieldsFrom": "listing"
}
],
"postCount": 12,
"hasMore": true,
"nextCursor": "QVFEZ..."
}