One URL in. Clean JSON out.
Give this endpoint a public Instagram Reel or video post URL and it hands back a direct link to the underlying MP4, plus the clip's duration. We do not host, re-encode or proxy the file — the link points at Instagram's own CDN, and you fetch the bytes yourself. One call costs 40 credits.
The difference
On the left, what a headless browser hands you. On the right, what the endpoint hands you.
<article class="_aagv _ab8w x1n2onr6" role="presentation"><div class="x9f619 xjbqb8w x78zum5"><div class="_aagu"><img alt="Photo by @creator" class="x5yr21d xu96u03" src="https://scontent.cdninstagram.com/v/t51...blob"/></div><section class="x6s0dn4 x78zum5 xdt5ytf"><span class="x1lliihq _aacl _aaco">55,210 likes</span><div class="_a9zs"><span dir="auto">Three settings you should change today</span></div><span class="_aacl _aaco x1i10hfl">View all 981 comments</span></section><time class="_aaqe" datetime="2026-07-03T12:00:00.000Z">18h</time></div><script type="application/json" data-sjs>{"require":[["ScheduledServerJS","handle",null,[{"__bbox"... {"data": {"platform": "instagram","entity_id": "C8xQvZ2sVAb","media_url": "https://cdn.example/video/master.mp4?sig=...","mime_type": "video/mp4","expires_at": "2026-07-15T13:00:00Z","warning": "media_url is short-lived (max 1h) — download promptly or re-request."},"request_id": "req_01JZX4M8Q2TE9W"}
The payload
A small object, deliberately. There are four keys: the post's shortcode, the media URL, the runtime in seconds, and a short note reminding you that the URL expires. If you also want the caption, like count or author, that is the Instagram Stats API — this endpoint is about getting to the file and nothing else.
The media URL is a signed CDN link. Instagram issues these with an embedded expiry and ties them loosely to the requesting context, so they are useful for minutes, not days. Fetch the file as soon as you have the link, store your own copy, and never write the CDN URL into a database as if it were permanent. If you serve it to a browser hours later it will 403 and you will spend an afternoon debugging something that is working as designed.
If the post has no video track — a single photo, a carousel of stills — the normalizer has nothing to return and the call fails rather than returning a half-object. That is intentional. A response either has a working media URL in it or it does not exist.
A fixed reminder string that media_url is a short-lived CDN link and should be downloaded promptly.
Pricing
One video is 40 credits — about 20¢ on the monthly plan, 18¢ on annual. $5 covers roughly 25 downloads, and failed calls, including photo-only posts, are never charged.
Estimate only, on a full-year basis. 40 credits per returned video. Monthly: $5 per 1,000 credits with $4/1,000 top-ups. Annual: $54 per 12,000 credits with $3/1,000 top-ups. We show whichever plan is cheaper for your annual volume, divided by 12. Failed calls are never charged; cache hits cost the same as fresh calls.
Entry price, side by side
Credits are not equivalent units across vendors — each meters differently. Price your own workload on both before deciding on entry price alone. At high volume, several of these are cheaper per credit than we are.
Engineering notes
We document exactly how every endpoint behaves — nulls, caching, billing — so what you ship on day one is still running in month six. No surprises, no support tickets.
Instagram signs CDN URLs with a short validity window. Treat the response as a one-shot fetch instruction: call the endpoint, immediately GET the media_url, write the bytes to your own storage, then discard the URL.
A 403 from Instagram on a link you fetched hours after it was issued is the expected outcome, not a fault in the call — the endpoint worked and the link simply aged out. If you need the file again later, call again rather than retrying the stale URL.
At 40 credits a video this is one of the more expensive calls in the catalogue, because pulling media costs meaningfully more upstream than reading a page of text. At $0.005 per credit that is 20 cents per video on the monthly plan, 18 cents on annual.
So do not use it as a discovery tool. Filter first with the cheap list and stats endpoints, decide which handful of Reels you actually want the file for, and only then call download. Piping a whole channel through it unfiltered means paying 40 credits for every clip, including the ones you would never have watched.
This endpoint is cached in the near-immutable class, since a given Reel's file does not change. A repeat call for the same post inside the window returns in milliseconds with x-cache: hit — but note that a cached response can carry a media_url that has already expired, because the URL's clock is Instagram's, not ours.
If you get a cache hit and the link 403s, retry with fresh=true to force a new signed URL. Cached and fresh calls both cost 40 credits.
We read what a logged-out visitor can read. Private accounts, deleted posts, age-gated content and anything geo-restricted from our egress will error rather than return partial data. Failed calls are not charged.
Stories and content behind a follow request are out of scope entirely. There is no flag that changes this.
The file you get belongs to whoever made it. Archiving for internal research, analysis or your own back-up is one thing; reposting someone else's Reel to your own account is a copyright question and Instagram's terms apply to you regardless of how the bytes reached your disk. We give you access to public media, not a licence to it.
Questions
Send a GET to /v1/instagram/download with the Reel URL and your API key. The response contains media_url, a direct link to the MP4 on Instagram's CDN, which you then fetch with an ordinary HTTP client. There is no OAuth step and no Instagram developer app involved. The Graph API only reaches media on accounts you own and manage, which is why it does not solve this problem for most people.
Instagram signs its CDN links with a short expiry. The link is valid for minutes, not days, and it is not something we control or can extend. Download the file immediately and keep your own copy. If a stored link has stopped working, call the endpoint again with fresh=true to get a newly signed one rather than retrying the old URL.
40 credits per video. Credits are $0.005 each on the monthly plan and $0.0045 on annual, so a download is about 20 cents, or 18 cents annually. It is priced above the read endpoints because fetching media costs more upstream. Failed calls — private posts, photo-only posts, deleted content — are never charged.
No. This endpoint resolves a video track and returns nothing when there is not one, so a photo post or an image-only carousel errors out. If you need the still image for a post, the Instagram Stats API returns a thumbnail URL alongside the engagement data, and it costs a small fraction of a download call.
No, and it never will. Everything we read is fetched logged out, exactly as an anonymous visitor sees it. Private accounts, follower-only posts and Stories are unreachable, and calls against them return an error rather than a partial result. That limit is deliberate — we do not log in, hold sessions, or work around access controls.
You get whatever Instagram serves from its CDN for that post, unmodified. We do not re-encode, strip anything, or add anything. If the creator uploaded a clip that already carried a TikTok watermark, that watermark is in the file. There is no watermark-removal option on this endpoint.
Not in one call — this endpoint takes a single URL and returns a single file link. The usual pattern is two steps: call the Instagram Channel Reels API to list a creator's recent Reels, filter that list down to the ones you actually want, then call download for each. At 40 credits apiece, filtering before you download is worth the extra step.
Next
100 trial credits on signup — no card, key on screen immediately.