Instagram Reels video requirements for API uploads

Instagram's API cURLs a Reel from a public video_url: MP4 or MOV, H.264 or HEVC, 23–60 fps, 3 s to 15 min, 300 MB. How a Sume MP4 maps to each rule.

6 min readSume
All posts

To publish a Reel with Instagram's Graph API, you pass a video_url that Instagram cURLs from a public server. The file must be MOV or MP4 with the moov atom at the front, H.264 or HEVC at 23–60 fps, AAC audio at 48 kHz or less, at most 1,920 pixels wide, 3 seconds to 15 minutes long, and at most 300 MB. A Sume MP4 on media.sume.com is public, so its URL can go in video_url; check its probe values against that list first.

Instagram's rules are quoted from Meta's IG User Media reference and Content Publishing guide, and Facebook's from the Reels Publishing API guide, all read on 2026-09-27. Sume facts come from Timeline 1.0, Video trim, Audio detach, and Video inspect.

What are the Reels video requirements on Instagram and Facebook?

Instagram's reference lists one spec for Reels. Facebook Pages publish Reels through a separate API with its own spec:

From Meta's IG User Media, Content Publishing, and Reels Publishing API pages, read 2026-09-27.
SpecInstagram ReelsFacebook Reels
ContainerMOV or MP4, no edit lists, moov atom at the front.mp4 (recommended)
VideoHEVC or H.264, progressive, closed GOP, 4:2:0H.264, H.265, VP9, or AV1; 4:2:0; progressive; closed GOP of 2–5 s; fixed frame rate
Frame rate23–60 fps24–60 fps
PictureAt most 1,920 columns; ratio 0.01:1 to 10:1, 9:16 recommended9:16; 1080×1920 recommended, 540×960 minimum
Duration3 seconds to 15 minutes3 to 90 seconds
File size, video bitrate300 MB; VBR up to 25 MbpsNot listed
AudioAAC, 48 kHz maximum, mono or stereo, 128 kbpsAAC Low Complexity, 48 kHz, stereo, 128 kbps or more
Publishing limit100 API-published posts per 24 hours; the carousel section says 5030 API-published posts per 24 hours

How do I make a Reels-shaped video with Sume?

Generate with aspect_ratio: "9:16" (ratios by model) and a duration of at least 3 seconds; wan-3.0 accepts 2, under Instagram's minimum. For one clip, a POST /v1/video-trim re-encode with output: { width, height, fps } keeps its audio as AAC. For several clips, Timeline 1.0 renders 1080×1920 by default, inside Instagram's 1,920 columns and equal to Facebook's recommended size, and its output.fps values (24, 25, 30, 60) sit inside both frame-rate ranges.

Today a Timeline render takes its sound from the audio spine and optional soundtrack, not from the clips, so detach the clip's track with POST /v1/audio-detach and pass it as audio.url. A generated clip's own encoding isn't documented; the encoder settings below apply to Timeline, filter, and trim's default exact mode.

Which settings differ from Meta's list, and what fixes them?

Run a free frames: false inspect first; its probe reports fps, width, audio_sample_rate, audio_channels, and size_bytes. Then:

  • Sample rate and channels: Facebook lists 48 kHz stereo. Trim has no sample-rate field, and detach's channels takes only source or mono, so detach a stereo track with sample_rate: 48000, use it as the Timeline audio.url, and confirm audio_sample_rate and audio_channels on the result.
  • Audio bitrate and GOP: Sume's encoder writes AAC at 192 kbps and caps the GOP at about one second, with no setting for either (all encoder settings). 192 kbps clears Facebook's 128 kbps floor; Instagram's line gives 128 kbps without saying floor or cap. The GOP cap is shorter than Facebook's 2–5 s.
  • Video bitrate: there is no bitrate field, so compute size_bytes × 8 ÷ duration_seconds ÷ 1,000,000 and compare it with Instagram's 25 Mbps.
  • Progressive scan, edit lists, and GOP closure aren't described in Sume's docs; check them with your own tool if a container fails.

How do I hand the video to Instagram?

Take the MP4's media.sume.com URL from GET /v1/jobs/{id}/result. Completed jobs can include public artifacts there, and Sume-hosted media on media.sume.com does not expire (URL lifetime). Don't pass /v1/videos/{id}/content: it needs your API key. For a cover, POST /v1/video-frames returns durable JPEG stills at source size from clips up to 300 seconds; Instagram crops a non-9:16 cover_url to its middle 9:16.

Timeline, filter, and trim write their MP4 with +faststart, which FFmpeg's docs describe as moving the moov atom to the beginning. Create the container as Meta's reference shows, then call media_publish with the container id:

POST https://graph.facebook.com/v25.0/<IG_USER_ID>/media
  ?media_type=REELS
  &video_url=https://media.sume.com/artifacts/artf_demo/reel.mp4
  &cover_url=https://media.sume.com/artifacts/artf_demo/cover.jpg
  &access_token=<USER_ACCESS_TOKEN>

What else limits API publishing?

Meta's pages add limits that no file setting changes:

  • Containers expire after 24 hours, and an account can create 400 in a rolling 24 hours. Video uploads are asynchronous: publish once the container's status_code is FINISHED.
  • Meta's guide contradicts itself on the post limit: its rate-limit section says 100 API-published posts per 24-hour moving period, and its carousel section says 50 published posts per 24 hours. GET /<IG_ID>/content_publishing_limit shows an account's current usage.
  • is_ai_generated is an optional self-disclosure of AI use on the container.
  • Facebook's hosted-file upload rejects files on sites whose robots.txt blocks the facebookexternalhit user agent. Sume's docs don't cover robots.txt, so if that upload fails, send the file bytes instead.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume