Instagram media specs: why uploads fail
Instagram publishes exact media rules for its Graph API path — Stories cap at 60 seconds and 100MB while Reels allow 15 minutes and 1GB, carousels crop every card to the first item's aspect ratio, API images are JPEG-only, and every upload is re-encoded server-side — so most publish failures are spec failures you could have caught locally.
CLAIMS CARRY THEIR CONFIDENCE: DOCUMENTED = STATED BY THE PLATFORM OR IN A CITED PUBLIC SOURCE ·INFERENCE = REASONABLE DEDUCTION, NOT CONFIRMED · UNKNOWN = NOT PUBLIC, SAID SO INSTEAD OF GUESSED
The surface limits that actually bite
The spec table Meta publishes for the Graph API path is long, but two contrasts do most of the damage in practice: DOCUMENTED
- Stories are the tight surface — 60 seconds and 100MB, against 15 minutes and 1GB for Reels. A pipeline that treats "video is video" ships Stories rejections all day.
- A carousel crops every card to the first item's ratio, defaulting to 1:1 — a mixed-ratio carousel is silently cropped to whatever card one establishes. Order your cards knowing card one is the die everything else is cut with.

Image rules: JPEG in, everything else converted
The API accepts JPEG only — the extended JPEG formats MPO and JPS are explicitly unsupported. WebP, HEIC, HEIF and AVIF are converted to JPEG before posting, and the conversiondeliberately carries provenance metadata forward via XMP, including AI-disclosure fields — format conversion is not a metadata laundry. DOCUMENTED
The server re-encodes everything anyway
Instagram re-encodes every upload server-side into its own encoding families.DOCUMENTED Two consequences:
- Your encode's job is not to be final — it is to be accepted without quality-destroying surprises. Uploading at spec means the platform's transcode starts from clean input.
- Which transcode ladder any given account or surface gets is not publishedUNKNOWN — so "it looked worse after upload" is sometimes the ladder, not your file. Control what you can control: the input.
The preflight that saves containers
Because publishing burns a container per attempt, the cheap move is local validation before the API ever sees the file. The failure modes worth an ffprobe check: container format and codec, moov atom position, edit lists, aspect ratio inside the accepted range, duration and size against the target surface. Catching a bad moov locally costs milliseconds; catching it at the dock costs a container and a retry cycle.DOCUMENTED (the failure modes) · INFERENCE (the economics)
One honest caveat: the published table is authoritative for the API path; app-path limits are not documented with the same precision. UNKNOWN applies to any claim about what the app accepts.
Sources
- Content Publishing — Instagram Platform, Meta for Developers (media specifications for the API publishing path)
- Confidence markers follow the discipline of the Altineris research set: a number without a citation is treated as a fabrication.