Skip to Content

Instagram Upload API

This section details how to upload photos, videos, reels, stories, and carousels to Instagram using the API.

Base URL

https://api.multi-upload-tool.com/api/v1

Authentication

All requests require an API Token in the header: x-api-key: YOUR_API_TOKEN


Requirements

Instagram Video Requirements

  • Container Format: MOV or MP4 (MPEG-4 Part 14), no edit lists, moov atom at head.
  • Audio Codec: AAC, 48 kHz max, 1-2 channels, 128 kbps.
  • Video Codec: HEVC or H264, progressive scan, closed GOP, 4:2:0 chroma subsampling.
  • Video Bitrate: VBR, max 25 Mbps.
  • Frame Rate: 23-60 FPS.
  • Resolution: Max width 1920px.
  • Aspect Ratio: 0.01:1 to 10:1 (Recommended 9:16 to avoid cropping).
  • Duration: 3 seconds to 15 minutes.
  • File Size: Max 300 MB.

Instagram Photo Requirements

  • Formats: PNG, JPEG, GIF.
  • File Size: Max 8 MB.
  • Media Types: IMAGE (Feed), STORIES (JPEG only — see Publish a Story).
  • Carousels: Up to 10 images/videos.

Validation & Limits

The API enforces the following constraints. Some limits are recommended by Instagram (via their Platform documentation ); others are enforced by us before submission.

ConstraintLimitEnforcedNotes
Video file size300 MBYesPer file in carousel or single video. Files over 100 MB must use presigned uploads — a single request is capped at 100 MB by our edge.
Image file size8 MBYesPer file in carousel or single image
Caption length2200 charactersYes (by us)Recommended by Instagram; we reject over the limit
Hashtags in captionMax 30YesWe count and reject captions with >30 hashtags
@-mentions in captionMax 20YesWe count and reject captions with >20 mentions
Collaborators per postMax 3YesInstagram-enforced limit; we validate on submit
Carousel items2–10YesMinimum 2, maximum 10 items per carousel
Video codecHEVC or H.264RecommendedInstagram’s official spec; we accept per file type
Video resolutionMax 1920px widthRecommendedInstagram’s official spec
Video aspect ratio0.01:1 to 10:1RecommendedInstagram’s official spec
Video duration3 sec – 15 minRecommendedInstagram’s official spec for Reels/Feed videos
Story media1 JPEG ≤ 8 MB, or 1 MP4/MOV of 3–60 s ≤ 100 MBYesSee Publish a Story

Upload Photo

Upload a single photo or a story to a connected Instagram account.

Endpoint

POST /upload

Content-Type

multipart/form-data

Parameters

Query Parameters

ParameterTypeRequiredDescription
asyncstringNoDefault "true". If "false", the API waits for upload completion.

Body Parameters

ParameterTypeRequiredDescription
accountIdstringYesThe ID of the connected Instagram account.
photoFileYesThe image file to upload.
titlestringNoThe caption for the post.
media_typestringNoIMAGE (Feed), STORIES. Auto-detected from file type and count if omitted.
schedule_datestringNoISO 8601 date string to schedule the post (e.g., 2025-12-25T10:00:00Z).
location_idstringNoInstagram Location ID to tag a place.
collaboratorsstringNoComma-separated list of usernames to invite as collaborators.
user_tagsstringNoComma-separated list of usernames to tag in the image.
is_aigcboolean | stringNoSelf-disclose AI usage. Instagram may add an “AI info” label to the post.

Example Request (Photo)

curl -X POST https://api.multi-upload-tool.com/api/v1/upload \ -H "x-api-key: YOUR_API_TOKEN" \ -F "accountId=cmf3k9x2a0001l408q7vbn2hd" \ -F "photo=@/path/to/image.jpg" \ -F "title=Hello Instagram! #vibes" \ -F "media_type=IMAGE" \ -F "location_id=123456789"

Upload Video

Upload a single video, reel, or video story to a connected Instagram account.

Endpoint

POST /upload

Content-Type

multipart/form-data

Parameters

Query Parameters

ParameterTypeRequiredDescription
asyncstringNoDefault "true". If "false", the API waits for upload completion.

Body Parameters

ParameterTypeRequiredDescription
accountIdstringYesThe ID of the connected Instagram account.
videoFileYesThe video file to upload.
titlestringNoThe caption for the post (Reels/Feed).
media_typestringNoVIDEO, REELS, STORIES. Default: REELS.
schedule_datestringNoISO 8601 date string to schedule the post.
cover_urlstringNoCustom cover image URL for Reels/Videos.
location_idstringNoInstagram Location ID to tag a place.
collaboratorsstringNoComma-separated list of usernames to invite as collaborators.
share_to_feedbooleanNoWhether to share Reels to Feed. Default: true.
trial_reelstringNomanual or auto: publish as a Trial Reel, shown to non-followers first. manual = you graduate it to your followers in the Instagram app; auto = Instagram graduates it if it performs well. Single-video Reels only: with a photo, carousel or story the request is refused (400) instead of posting to your followers. The account must be eligible for Trial Reels.
audio_namestringNoReels only. Custom display title for the Reel’s original audio (renames the audio shown to viewers — can only be set once). Does not attach a track from Instagram’s music library; the Instagram Platform API does not expose music selection for any media type.
thumb_offsetstringNoTime offset (in ms) for the video thumbnail.
is_aigcboolean | stringNoSelf-disclose AI usage. Instagram may add an “AI info” label to the post.

Example Request (Video/Reel)

curl -X POST https://api.multi-upload-tool.com/api/v1/upload \ -H "x-api-key: YOUR_API_TOKEN" \ -F "accountId=cmf3k9x2a0001l408q7vbn2hd" \ -F "video=@/path/to/video.mp4" \ -F "title=My new reel! 🎥" \ -F "media_type=REELS" \ -F "cover_url=https://example.com/cover.jpg"

Upload a carousel (album) containing up to 10 photos and/or videos.

Endpoint

POST /upload

Content-Type

multipart/form-data

Parameters

Query Parameters

ParameterTypeRequiredDescription
asyncstringNoDefault "true". If "false", the API waits for upload completion.

Body Parameters

ParameterTypeRequiredDescription
accountIdstringYesThe ID of the connected Instagram account.
photoFile[]YesArray of files (images and/or videos). Use the key photo for all items.
titlestringNoThe caption for the carousel.
schedule_datestringNoISO 8601 date string to schedule the post.
location_idstringNoInstagram Location ID to tag a place.
collaboratorsstringNoComma-separated list of usernames to invite as collaborators.
user_tagsstringNoComma-separated list of usernames to tag in the first image.
is_aigcboolean | stringNoSelf-disclose AI usage. Applies to the carousel as a whole, not to individual items.

Note on music: The Instagram Platform API does not allow attaching music from Instagram’s library to a carousel (or to any other media type). There is no audio_id / music_id parameter — this is an Instagram-side limitation. To add a song from the Instagram music library, open the published post in the Instagram app and add music there.

curl -X POST https://api.multi-upload-tool.com/api/v1/upload \ -H "x-api-key: YOUR_API_TOKEN" \ -F "accountId=cmf3k9x2a0001l408q7vbn2hd" \ -F "photo=@/path/to/photo1.jpg" \ -F "photo=@/path/to/video2.mp4" \ -F "photo=@/path/to/photo3.jpg" \ -F "title=My mixed media dump 📸🎥"

Example Response

{ "success": true, "message": "Upload queued successfully", "data": { "uploadId": 789, "status": "pending", "jobId": "job_456" } }

Publish a Story

Set media_type=STORIES and the post goes to the account’s story instead of the feed. Same endpoint, same connection — nothing extra to authorise.

A story is not a short post, and Instagram’s API is strict about it:

  • One media, and only these formats: a JPEG image up to 8 MB — a PNG is refused — or an MP4/MOV video of 3 to 60 seconds, up to 100 MB.
  • No caption. Instagram drops the text. We accept title/description so the same request shape works, but nothing is sent.
  • No collaborators, no location. Both are refused with a 400. Stickers (location, link, poll, mention) only exist in the Instagram app; the API publishes the media alone.
  • No AI label. is_ai_generated is not a story parameter. If you send is_aigc, the story publishes without it — the flag describes the content, and a bulk post may legitimately carry it for another platform.
  • It lasts 24 hours, then it is gone. There is no permanent URL, and a story never appears in Analytics.

What can be checked before anything is stored (media count, collaborators, location) is refused immediately with a 400. Format, size and duration are checked once the file is in hand; a story that breaks one of them fails with the reason, without retrying — the same file would fail the same way again.

Example Request (Story)

curl -X POST https://api.multi-upload-tool.com/api/v1/upload \ -H "x-api-key: YOUR_API_TOKEN" \ -F "accountId=cmf3k9x2a0001l408q7vbn2hd" \ -F "media_type=STORIES" \ -F "video=@/path/to/story.mp4"

In a bulk upload, use instagram_as_story=true instead of media_type: media_type applies to every platform of the batch, while instagram_as_story only turns the Instagram accounts’ posts into stories.