How to get Instagram channel reels
GET request to /v1/instagram/channel-reels with your input. You get clean JSON back in seconds for ~6 credits (0.3/result) per call — no OAuth, scraping or platform SDKs. Latest Reels from a public Instagram profile — pass userId to skip resolve; ceil(n×0.3) credits; nextCursor + hasMore.How to get Instagram channel reels (step by step)
- 1
Get a free API key
Create a free Captapi account (100 credits, no card) and generate an API key from the dashboard.
- 2
Call the Instagram Channel Reels API
Send an authenticated GET request to /v1/instagram/channel-reels with your input. No OAuth, no scraping setup.
- 3
Read the JSON response
Parse the clean JSON response. Pass cache=true for a free 24h cache hit; default is always fresh.
Code example
curl "https://api.captapi.com/v1/instagram/channel-reels?url=https%3A%2F%2Fwww.instagram.com%2Fcristiano%2F" \
-H "Authorization: Bearer capt_live_..."
# or: -H "x-api-key: capt_live_..."What the response looks like
{
"success": true,
"data": {
"url": "https://www.instagram.com/cristiano/",
"requested": 2,
"totalReturned": 2,
"reels": [
{
"platform": "instagram",
"url": "https://www.instagram.com/reel/Dcgs4DvIr3u/",
"id": "Dcgs4DvIr3u",
"shortcode": "Dcgs4DvIr3u",
"mediaId": "3971891348174241278",
"caption": "CR7 Fragrances. Made to move with you. @cr7cristianoronaldo",
"publishedAt": "2026-08-27T16:03:11.000Z",
"durationSeconds": 21.68,
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.71878-15/579431142_18553402342054533_2777016462962wm_n.jpg?...&oe=6AA4A207",
"videoUrl": "https://scontent.cdninstagram.com/o1/v/t2/f2/m86/AQOZ-XzJOT5OaiKkSWI8_rvZDNem.mp4?efg=eyJkdXJhdGlvbl9zIjogMjF9&oe=6AA0E161",
"videoUrlExpiresAt": "2026-09-09T04:32:33Z",
"thumbnailUrlExpiresAt": "2026-09-12T04:51:19Z",
"hasAudio": true,
"author": {
"id": "1421738679",
"username": "cr7cristianoronaldo",
"displayName": "CR7 Fragrances",
"url": "https://www.instagram.com/cr7cristianoronaldo/",
"verified": true,
"avatar": "https://scontent.cdninstagram.com/v/t51.2885-19/324775217_1234.jpg?...",
"followers": null,
"isPrivate": false
},
"coauthors": [
{
"id": "173560420",
"username": "cristiano",
"displayName": "Cristiano Ronaldo",
"url": "https://www.instagram.com/cristiano/",
"verified": true,
"profileImage": "https://scontent.cdninstagram.com/v/t51.2885-19/472007201_n.jpg?..."
}
],
"engagement": {
"likes": 1658553,
"comments": 20928,
"views": 50204153,
"likesIsApproximate": false,
"commentsIsApproximate": false,
"viewsIsApproximate": false,
"viewsSource": "instagram"
},
"hashtags": [],
"mentions": [
"cr7cristianoronaldo"
],
"isPaidPartnership": false,
"isAd": false,
"isAffiliate": false,
"likeAndViewCountsDisabled": false,
"music": {
"id": "28202524666022877",
"title": "Original audio",
"artist": "cr7cristianoronaldo",
"clusterId": null,
"assetId": null,
"canonicalId": null,
"artistId": null,
"durationMs": null,
"audioType": "original_sounds",
"coverUrl": null,
"isTrendingInClips": false,
"isExplicit": null,
"hasLyrics": null
},
"musicId": "28202524666022877"
},
{
"platform": "instagram",
"url": "https://www.instagram.com/reel/DaU63nnAkoo/",
"id": "DaU63nnAkoo",
"shortcode": "DaU63nnAkoo",
"mediaId": "3933027283400542760",
"caption": "Toronto ❤️",
"publishedAt": "2026-07-03T10:18:59.000Z",
"durationSeconds": 46.333,
"thumbnailUrl": "https://scontent.cdninstagram.com/v/t51.82787-15/731058572_18747860116056421_n.jpg?...&oe=6AA4CEDE",
"videoUrl": "https://scontent.cdninstagram.com/o1/v/t2/f2/m86/AQNreyyq7N-5e2XVjCTkh7BFZ0wKTqOp.mp4?...&oe=6AA0F2A1",
"videoUrlExpiresAt": "2026-09-09T03:44:02Z",
"thumbnailUrlExpiresAt": "2026-09-12T04:14:49Z",
"hasAudio": true,
"author": {
"id": "173560420",
"username": "cristiano",
"displayName": "Cristiano Ronaldo",
"url": "https://www.instagram.com/cristiano/",
"verified": true,
"avatar": "https://scontent.cdninstagram.com/v/t51.2885-19/472007201_1142000150877579_n.jpg?...",
"followers": 679721682,
"isPrivate": false
},
"coauthors": [],
"engagement": {
"likes": 19495500,
"comments": 368088,
"views": 217575248,
"likesIsApproximate": false,
"commentsIsApproximate": false,
"viewsIsApproximate": false,
"viewsSource": "instagram"
},
"hashtags": [],
"mentions": [],
"isPaidPartnership": false,
"isAd": false,
"isAffiliate": false,
"likeAndViewCountsDisabled": false,
"music": {
"id": "1153749292279414",
"title": "Original audio",
"artist": "cristiano",
"clusterId": null,
"assetId": null,
"canonicalId": null,
"artistId": null,
"durationMs": null,
"audioType": "original_sounds",
"coverUrl": null,
"isTrendingInClips": false,
"isExplicit": null,
"hasLyrics": null
},
"musicId": "1153749292279414"
}
],
"nextCursor": "3971891348174241278_1421738679",
"hasMore": true,
"userId": "173560420",
"user": {
"id": "173560420",
"username": "cristiano",
"displayName": "Cristiano Ronaldo",
"url": "https://www.instagram.com/cristiano/",
"verified": true,
"isPrivate": false,
"avatar": "https://scontent.cdninstagram.com/v/t51.2885-19/472007201_1142000150877579_n.jpg?...",
"followers": 679721682,
"postCount": 4126
},
"degraded": false,
"degradedReason": null,
"fetchedAt": "2026-09-07T18:02:44.132Z"
}
}Billing metadata (credits charged, cache hit/miss) is returned in the X-Captapi-Credits and X-Captapi-Cache response headers.
Request parameters
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | No | Instagram profile URL, @handle, or username. Omit when userId is set. The URL platform must match this endpoint's platform. |
| userId | string | No | Instagram numeric user ID (e.g. 173560420). Skips handle→ID resolve (legacy sequential WPI alone could cost ~80s). Prefer when you already have the ID from basic-profile or profile-search. |
| limit | integer | No | Max items to return (default 20, max 200). Billed per result. |
| cursor | string | No | Pagination cursor. Leave empty for the first page; then pass nextCursor from the previous response (clips:{userId}:{opaque} on the native Reels path, or legacy {mediaId}_{userId}). Stop when hasMore is false. |
| cache | boolean | No | Set true to serve from the 24h response cache (0 credits on hit). Default false — always fetch fresh. |
Frequently asked questions
What does the Instagram Channel Reels API do?
The Instagram Channel Reels API lets you list items in bulk with metadata from a public Instagram channel reels using one GET request to /v1/instagram/channel-reels. It returns clean JSON — no OAuth or infrastructure setup required.
How many credits does the Instagram Channel Reels API cost?
At the default limit this endpoint costs 6 credits (0.3 per result). Billing scales with how many results you request. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Failed or empty results are never charged.
Do I need a Instagram API key or OAuth?
No. A single Captapi key works across every platform Captapi supports — YouTube, TikTok, Instagram, Facebook, Twitter/X, Reddit, Threads, Bluesky, Pinterest, LinkedIn, Rumble, Spotify, Kwai, and more. We handle proxies, rate limits, retries, and authentication for you.
Why is this 502 UPSTREAM_UNAVAILABLE on foodnetwork / cnn / theverge?
Not the URL — instagram.com/foodnetwork/ is the correct form (Threads uses /@handle; Instagram does not need the @). Those 502s were a cascade miss: native clips empty, Decodo's GraphQL scrape killed at 16s, then an empty or hung actor ran to ~98s. First-seen brands have no last-good. Decodo now races the actor until the 100s wall; the first path with reels wins. An empty actor no longer 502s while Decodo is still scraping. A miss with no snapshot is still 502 (retryable, 0 credits). Prefer userId from basic-profile to skip resolve.
Why did a cache hit take 24 seconds — and how old is the data?
A 24s stale response is a rescue, not a plan: the live paths (native clips, Decodo, the actor) were tried first, missed, and the 6h last-good snapshot was served instead of a 502. The age is now checkable — fetchedAt is when the data came from Instagram, servedAt is when we handed it over; the gap is how stale it is. fetchedAt is never restamped to the request time (it used to be, which made stale:true unactionable).
I queried cristiano and reels[].author is someone else. Is author the audio's owner?
No — author is always the post owner, never the audio attribution (verified against licensed-track reels where author ≠ music.artist). What you saw is Instagram's Collaborator feature: one reel lives on both profiles and the clips tab returns it with the original poster as author. Check coauthors[] — the queried channel is listed there. If you filter "reels authored by X", filter on author + coauthors or you will silently drop collab rows.
A handle that worked this morning now 502s on every retry. Is the endpoint down?
Check the status code first: a deleted, renamed, or banned account is now a non-retryable 404 PROFILE_NOT_FOUND, decided the moment Instagram's own "page isn't available" marker is seen — no scraper detour, no retry loop. The verdict is also remembered for 6 hours, so every poll of a confirmed-dead handle answers 404 instantly instead of re-litigating the resolve (which could blip into a 502 when Instagram rate-limited the check). It used to surface as retryable 502 UPSTREAM_UNAVAILABLE, which sent pollers into 20–55s retries against a dead handle all day. 502 still means a transient miss worth retrying; 404 means update the handle (renames keep the account but kill the old URL).
Is the Instagram Channel Reels API suitable for production use?
Yes. It is a stable REST endpoint with predictable JSON and automatic retries. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Use it for analytics, monitoring, and content automation.
Ready to get Instagram channel reels?
Start free with 100 credits — no credit card required.
Get your free API key