How to Schedule Instagram Reels via API
Instagram's Graph API doesn't accept future timestamps for Reels. Here's how to schedule Reels with Postproxy — container handling, processing waits, and exact-time publishing.
The Reels publishing flow, briefly
The Graph API splits Reel publishing into three calls:
POST /{ig-user-id}/mediawithmedia_type=REELSand avideo_url— returns a containerid.GET /{container-id}?fields=status_code— poll untilstatus_codeisFINISHED(5–60 seconds).POST /{ig-user-id}/media_publishwith the containerid— Reel goes live.
There’s no fourth call that says “and publish this at 8:00 AM Saturday.” If you want scheduled Reels, you own the timer — and that means OAuth refresh, container expiry handling (24h), retry on transient errors, and process-restart durability.
Schedule a Reel for an exact time
Postproxy holds the post and the OAuth token, runs the container/poll/publish dance at the right moment, and exposes a single request:
curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "30 seconds on what we built this week. #buildinpublic", "scheduled_at": "2026-05-09T08:00:00-07:00" }, "profiles": ["instagram"], "media": ["https://yourcdn.com/weekly-recap-9x16.mp4"], "platforms": { "instagram": { "format": "reel" } } }'The format: "reel" tells Postproxy to use the Reels container path. Without it, single-video posts default to feed format.
If a video is supplied without format, the publish lands in the feed. To explicitly target Reels, always pass format: "reel".
Reels-specific options
Instagram’s Reels container accepts a few extras:
{ "platforms": { "instagram": { "format": "reel", "first_comment": "Full breakdown ↓", "cover_url": "https://yourcdn.com/cover.jpg", "audio_name": "Original Audio", "thumb_offset": "5000", "collaborators": ["partner_handle"] } }}first_comment— auto-posts as the first reply to your Reel (max 2,196 chars). The classic “link in bio” play.cover_url— explicit cover image. Postproxy downloads it so it stays available at publish time.thumb_offset— millisecond offset into the video to use as cover. If bothcover_urlandthumb_offsetare set,cover_urlwins.collaborators— up to 3 IG handles to invite as collaborators.
Reels media specs
Validated upfront so you find out before the container fails:
- Container: MP4 or MOV, H.264 video / AAC audio
- Aspect ratio: 9:16 is the canonical Reels frame; other ratios get cropped or letterboxed in playback
- Resolution: at least 540×960; recommended 1080×1920
- Duration: 3 seconds to 90 minutes
- File size: max 300 MB
- Caption (
post.body): max 2,200 characters
Still images can’t publish as a Reel — the API rejects them. For carousels, see the Instagram carousel guide.
In Python (with the SDK)
pip install postproxy-sdk
import asynciofrom datetime import datetime, timezone, timedeltafrom postproxy import PostProxy, PlatformParams, InstagramParams
async def main(): publish_at = (datetime.now(timezone.utc) + timedelta(days=2)).replace( hour=15, minute=0, second=0, microsecond=0 )
async with PostProxy("your-api-key", profile_group_id="pg-abc") as client: post = await client.posts.create( "Tutorial Tuesday: how we generate test data.", profiles=["instagram"], media=["https://yourcdn.com/tutorial-tuesday.mp4"], scheduled_at=publish_at.isoformat(), platforms=PlatformParams( instagram=InstagramParams( format="reel", first_comment="Repo link below — drop a 🔧 if useful.", ), ), ) print(f"Reel scheduled: {post.id} for {post.scheduled_at}")
asyncio.run(main())Watching the publish complete
After scheduled_at passes, the post’s top-level status moves through processing → processed. The Instagram-specific subrecord shows the final state and the live permalink:
post = await client.posts.get(post_id)ig = next((p for p in post.platforms if p.platform == "instagram"), None)if ig and ig.status == "published": print(ig.permalink)Webhooks are an option if you’d rather not poll — see webhooks vs polling.
Other Instagram formats
The same request shape covers feed video — format: "post", or omit it. Stories work differently enough to have their own guide: no caption, single media only, and a 24-hour lifetime that makes publish timing matter more. See scheduling Instagram Stories via API.
For the deeper walkthrough of containers, status polling, and edge cases, see the Instagram Reels API publishing guide.