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.
| Constraint | Limit | Enforced | Notes |
|---|---|---|---|
| Video file size | 300 MB | Yes | Per 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 size | 8 MB | Yes | Per file in carousel or single image |
| Caption length | 2200 characters | Yes (by us) | Recommended by Instagram; we reject over the limit |
| Hashtags in caption | Max 30 | Yes | We count and reject captions with >30 hashtags |
| @-mentions in caption | Max 20 | Yes | We count and reject captions with >20 mentions |
| Collaborators per post | Max 3 | Yes | Instagram-enforced limit; we validate on submit |
| Carousel items | 2–10 | Yes | Minimum 2, maximum 10 items per carousel |
| Video codec | HEVC or H.264 | Recommended | Instagram’s official spec; we accept per file type |
| Video resolution | Max 1920px width | Recommended | Instagram’s official spec |
| Video aspect ratio | 0.01:1 to 10:1 | Recommended | Instagram’s official spec |
| Video duration | 3 sec – 15 min | Recommended | Instagram’s official spec for Reels/Feed videos |
| Story media | 1 JPEG ≤ 8 MB, or 1 MP4/MOV of 3–60 s ≤ 100 MB | Yes | See 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
| Parameter | Type | Required | Description |
|---|---|---|---|
async | string | No | Default "true". If "false", the API waits for upload completion. |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | The ID of the connected Instagram account. |
photo | File | Yes | The image file to upload. |
title | string | No | The caption for the post. |
media_type | string | No | IMAGE (Feed), STORIES. Auto-detected from file type and count if omitted. |
schedule_date | string | No | ISO 8601 date string to schedule the post (e.g., 2025-12-25T10:00:00Z). |
location_id | string | No | Instagram Location ID to tag a place. |
collaborators | string | No | Comma-separated list of usernames to invite as collaborators. |
user_tags | string | No | Comma-separated list of usernames to tag in the image. |
is_aigc | boolean | string | No | Self-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
| Parameter | Type | Required | Description |
|---|---|---|---|
async | string | No | Default "true". If "false", the API waits for upload completion. |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | The ID of the connected Instagram account. |
video | File | Yes | The video file to upload. |
title | string | No | The caption for the post (Reels/Feed). |
media_type | string | No | VIDEO, REELS, STORIES. Default: REELS. |
schedule_date | string | No | ISO 8601 date string to schedule the post. |
cover_url | string | No | Custom cover image URL for Reels/Videos. |
location_id | string | No | Instagram Location ID to tag a place. |
collaborators | string | No | Comma-separated list of usernames to invite as collaborators. |
share_to_feed | boolean | No | Whether to share Reels to Feed. Default: true. |
trial_reel | string | No | manual 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_name | string | No | Reels 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_offset | string | No | Time offset (in ms) for the video thumbnail. |
is_aigc | boolean | string | No | Self-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 Carousel
Upload a carousel (album) containing up to 10 photos and/or videos.
Endpoint
POST /upload
Content-Type
multipart/form-data
Parameters
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
async | string | No | Default "true". If "false", the API waits for upload completion. |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId | string | Yes | The ID of the connected Instagram account. |
photo | File[] | Yes | Array of files (images and/or videos). Use the key photo for all items. |
title | string | No | The caption for the carousel. |
schedule_date | string | No | ISO 8601 date string to schedule the post. |
location_id | string | No | Instagram Location ID to tag a place. |
collaborators | string | No | Comma-separated list of usernames to invite as collaborators. |
user_tags | string | No | Comma-separated list of usernames to tag in the first image. |
is_aigc | boolean | string | No | Self-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_idparameter — 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.
Example Request (Carousel)
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/descriptionso 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_generatedis not a story parameter. If you sendis_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.