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:

  1. POST /{ig-user-id}/media with media_type=REELS and a video_url — returns a container id.
  2. GET /{container-id}?fields=status_code — poll until status_code is FINISHED (5–60 seconds).
  3. POST /{ig-user-id}/media_publish with the container id — 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:

Terminal window
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 both cover_url and thumb_offset are set, cover_url wins.
  • 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 asyncio
from datetime import datetime, timezone, timedelta
from 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 processingprocessed. 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.

Stories and feed posts

The same shape applies to Stories (format: "story") and feed video (format: "post" or omit). Stories don’t allow text content — captions are ignored.

For the deeper walkthrough of containers, status polling, and edge cases, see the Instagram Reels API publishing guide.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.