Instagram Reel Uploader
Auto-post Reels to your own Instagram account from a video URL with caption and hashtags. Bring your own session cookies.
How it works
- 1Open it on Apify
Hit Run on Apify — it opens the tool in the cloud, no install.
- 2Set the inputs
Adjust
videoUrl,caption,cookies(sensible defaults are pre-filled). - 3Click Run
The tool runs on Apify’s cloud and collects the data for you.
- 4Export the results
Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.
Pricing
$0.1 per reel uploaded to Instagram = $100 per 1,000
| You are charged for | When | Price |
|---|---|---|
| Reel uploaded to Instagram | Charged once per SUCCESSFUL Instagram Reel upload (failed runs are free). | $0.1 |
| Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.000025 |
Pay-per-event pricing: you are billed per result, not per subscription — a run that returns nothing costs nothing beyond the start fee. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-08, and they are what you are actually charged.
Inputs
| Field | What it does | Type |
|---|---|---|
videoUrl | Public direct https URL to the video (.mp4) to upload as a Reel. Required for a real post; leave everything empty to get one free labelled sample row instead. | string |
caption | The Reel caption (include #hashtags here). | string |
cookies | Your Instagram session cookies, from a browser where YOU are logged in. Paste either a Cookie-Editor JSON export (recommended) or the raw 'Cookie:' header string from DevTools. Must contain sessionid and ds_user_id. Automates your own session. Kept private. | string |
demoMode | Run without credentials and return one clearly-labeled SAMPLE row without uploading anything. Also auto-enabled when no cookies are supplied (e.g. a keyless try-it run). | boolean |
What you get
A structured dataset — each result includes fields like:
okchargeddemoplatformcaptionconfirmedreelUrlfinalUrlerrorCodeerrorhintnoteExport every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.
Related tools in Social Publishing & Uploaders
Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.
YouTube Video Uploader
Upload videos to your YouTube channel from a URL with no code: set title, tags, privacy, thumbnail, and schedule an auto-publish time via OAuth.
Instagram Scraper - Profiles, Posts & Reels (No Login)
Keyless Instagram scraper: profiles, posts and reels in one run. Likes, comments, views, media, hashtags. No login or API key. From $0.45/1k results.
Instagram Comments Scraper
Scrape Instagram post and reel comments at $0.40 per 1,000, flat at every volume, plus a $0.001 run start. Text, likes, replies, author, verified badge.
Where this tool sits
- Categories
- Social Publishing & Uploaders
- Platforms
Instagram Reel Uploader
Posts a Reel to your own Instagram account from a URL. You give it the video, a caption, and your own exported session cookies, and it drives a headless browser through Instagram's web composer to publish the Reel. It's built to be the publish step of a faceless-content or scheduling pipeline.
How it works
It downloads your video, launches a headless Chromium routed through your proxy, loads your exported Instagram cookies into the session, opens the Create composer on instagram.com, sets the file, advances through the crop and edit steps, writes the caption, and shares. There is no shared login. You bring your own session each run, exported from a browser where you're already signed in.
Try it with no login (demo / sample mode)
Run it with no cookies (or set demoMode: true) and it returns one clearly-labeled sample row and uploads nothing — a try-before-you-export preview. The sample row carries _demo: true and a _notice explaining that no credentials were supplied. To post for real, supply your own session (below).
Input
| Field | Required | Notes |
|---|---|---|
videoUrl | for real posts | Public https direct URL to the .mp4 to post as a Reel. You host it. Max 600 MB. |
cookies | for real posts | Your own Instagram session, exported as Cookie-Editor JSON from a browser where you're logged in. Must include sessionid and ds_user_id. Stored as a secret. |
caption | no | The Reel caption. Put your #hashtags here. |
proxyConfiguration | no | Leave on the default. The Actor supplies (and pays for) its own residential connection, because Instagram checkpoints datacenter addresses; the proxy group you pick is ignored. Your own servers in proxyUrls are used verbatim, and unticking "Use Apify Proxy" connects directly. |
demoMode | no | Return a labeled sample row without uploading. Auto-enabled when no cookies are given. |
How to export your Instagram cookies
1. Log in to instagram.com in Chrome/Edge. 2. Install the Cookie-Editor extension and open it on the Instagram tab. 3. Click Export → Export as JSON (this copies a cookies array including sessionid and ds_user_id). 4. Paste that JSON into the cookies field. It is automating your own logged-in session — nothing is shared.
Output
Exactly one dataset record per run, always.
- Demo run:
{ _demo: true, _sample: true, _notice, ok: true, demo: true, charged: false, reelUrl: ".../reel/SAMPLE/", ... }— nothing uploaded. - Real success:
{ ok: true, charged: true, platform, caption, posted: true, confirmed: true, reelUrl, finalUrl }—confirmedis onlytrueafter Instagram's "has been shared" confirmation is actually seen, andreelUrlis the real permalink when it can be read. - Anything else:
{ ok: false, charged: false, errorCode, error, reason, hint }— a diagnostic row naming what went wrong and what to do about it, plus a debug screenshot + page HTML saved in the run's key-value store and named in the row.
A run that cannot post does not fail — it returns the diagnostic row and ends as SUCCEEDED. A failed run and a succeeded run cost you the same platform start fee, so crashing would charge you the same and tell you less. The instagram-upload charge fires only on the confirmed-success path.
Error codes
errorCode | What happened | What to do |
|---|---|---|
BAD_INPUT | videoUrl or cookies was missing or unusable. | Fix the field named in error. |
VIDEO_UNAVAILABLE | The videoUrl did not download. | Open it in a private window; it must return the .mp4 directly. |
SESSION_INVALID | The cookies are expired or were exported logged out. | Re-export with Cookie-Editor while signed in. |
SESSION_CHECKPOINT | Instagram put the account behind a security check. | Clear it in a normal browser, then re-export the cookies. |
UPLOAD_REJECTED | Instagram refused the post (action block, rate limit, file rejected). | Wait a few hours, post less often, use a residential proxy in your country. |
UPLOAD_UNCONFIRMED | Share was clicked but no confirmation appeared. | Check the account before retrying — a blind retry can double-post. |
LAYOUT_CHANGED | Instagram's composer no longer matches the steps this Actor drives. | Nothing on your side; report the run so the selectors can be updated. |
NETWORK | A network or proxy error stopped the run reaching Instagram. | Retry, or switch proxy country. |
TIMED_OUT | The run hit its time budget and stopped itself. | Check the account, then retry with a longer timeout. |
INTERNAL | Unexpected error. | Report the run id with the saved screenshot. |
Method & reliability
This is a best-effort browser-automation method: it drives Instagram's real web "Create" composer (there is no official Reels upload API for personal accounts). It checks your session is logged in before downloading your video, selects Reel where offered, advances through the crop/cover/edit steps with explicit waits and several fallback selectors per step, verifies the file registered and the caption took, then watches for either Instagram's "has been shared" confirmation or an explicit refusal for up to 3 minutes.
Because it depends on Instagram's live UI, a layout change on their side can break a step. When that happens you get a LAYOUT_CHANGED row and a screenshot, not a silent wrong result and not a charge.
Example
{
"videoUrl": "https://cdn.example.com/reel.mp4",
"caption": "behind the scenes #reels",
"cookies": "[{\"name\":\"sessionid\",\"value\":\"...\",\"domain\":\".instagram.com\",\"path\":\"/\"}]"
}
Pricing
$0.35 per successful upload, plus a $0.000025 run-start fee — the start fee is billed once per GB of run memory, so at the default 2 GB a run start costs $0.00005.
This price takes effect on 31 August 2026. Runs before that date still bill the previous $0.10 per successful upload; runs from 31 August 2026 onward bill $0.35. The run-start fee is unchanged.
The upload charge fires only after Instagram confirms the Reel is live. Any run that ends in ok: false — bad input, dead cookies, a checkpoint, an action block, an unconfirmed share — pays the start fee and nothing else. Demo/sample runs are not charged for an upload either.
Proxy bandwidth is not billed to you. The Actor routes through its own residential connection and absorbs that cost. That absorbed bandwidth is what the 31 August 2026 rate covers, and it is also why a video sent over it is capped at 100 MB — a Reel is normally well under that. If you need the full 600 MB allowance, put your own proxy servers in proxyConfiguration.proxyUrls; they are used exactly as given and the cap lifts.
FAQ
Is there an official Instagram Reels upload API? No. Meta's Content Publishing API only covers Instagram Business and Creator accounts connected to a Facebook Page, and it needs an app review. This Actor drives the normal instagram.com web composer with your own logged-in session instead, so it works with a personal account.
Do you get my Instagram password? No. You paste session cookies, not credentials, and the field is stored as a secret. Log out of that Instagram session to revoke them.
Why did my run come back with SESSION_INVALID? Instagram session cookies expire, and they are also invalidated when you log out or change your password. Re-export them with Cookie-Editor from a tab where you are signed in.
Will I be charged if the Reel does not post? No. The instagram-upload event ($0.10 until 31 August 2026, $0.35 from that date) fires only after Instagram's own "has been shared" confirmation. Everything else returns an uncharged diagnostic row.
Can it post to a Story, a carousel, or a feed photo? No. Reels only, one video per run.
Why does it need a proxy? Instagram treats a datacenter address logging into your account as suspicious, so the Actor routes through a residential connection by default and pays for that bandwidth itself. You do not need to configure anything. Choosing a different proxy group in the input has no effect; supplying your own servers in proxyUrls, or turning the proxy off entirely, does.
What this does not do
- It does not create or find your video. You host the
.mp4and pass a public https URL. - It does not schedule. One run posts one Reel, immediately.
- It does not manage multiple accounts in one run. One session, one Reel.
- It cannot clear a checkpoint or an action block for you. Those need a real browser on the account.
- It does not guarantee delivery when Instagram changes its composer. That is reported as
LAYOUT_CHANGEDwith a screenshot, never as a silent success.
Notes
This automates your logged-in Instagram session, which Meta's terms discourage, so run it on your own account at your own discretion. Automating a session from a new device/IP is a pattern Instagram may flag with a temporary action-block or checkpoint — a residential proxy in your own country reduces (but does not eliminate) this. Cookies expire, so re-export them when you see a "not logged in" error. Because it drives Instagram's actual web UI, a layout change on their side can break a selector and need an update — failures are surfaced clearly with a saved screenshot, never as a silent success.