Instagram API
Schedule and automate Instagram posts with SocialSyncerAPI — Feed, Stories, Reels, Carousels, collaborators, and user tags.
Quick Reference
- Character limit: 2,200 (caption)
- Images per post: 1 (feed), 10 (carousel)
- Videos per post: 1
- Image formats: JPEG, PNG
- Image max size: 8 MB (auto-compressed)
- Video formats: MP4, MOV
- Video max size: 300 MB (feed/reels), 100 MB (stories)
- Video max duration: 90 sec (reels), 60 min (feed), 60 sec (story)
- Post types: Feed, Carousel, Story, Reel
- Scheduling: Yes
- Analytics: Yes
Before You Start
Google Drive, Dropbox, OneDrive, and iCloud links do not work as media URLs. These services return HTML pages, not media files. Instagram's servers cannot fetch media from them. Use direct CDN URLs or upload via SocialSyncerAPI's media endpoint.
- Media is required for all posts (no text-only)
- 100 posts per 24-hour rolling window (all content types combined)
- First 125 characters of caption are visible before the "more" fold
Quick Start
Post an image to Instagram in under 60 seconds:
Python (httpx)
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Check out this photo!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
)
data = resp.json()
print(f"Posted to Instagram! {data['id']}") curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Check out this photo!",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Node.js (fetch)
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Check out this photo!",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/photo.jpg" }
],
platforms: [
{ platform: "instagram", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
});
const data = await resp.json();
console.log("Posted to Instagram!", data.id); Content Types
Feed Post
A single image or video in the main feed. Best aspect ratio is 4:5 (portrait), but 1:1 (square) and 1.91:1 (landscape) are also supported. No contentType field is needed — feed is the default.
Feed Post — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Beautiful sunset today #photography",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/sunset.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
)
print("Feed post created!", resp.json()["id"]) Feed Post — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Beautiful sunset today #photography",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/sunset.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Feed Post — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Beautiful sunset today #photography",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/sunset.jpg" }
],
platforms: [
{ platform: "instagram", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
});
console.log("Feed post created!", (await resp.json()).id); Carousel
Up to 10 mixed image/video items. All items should share the same aspect ratio — the first item determines the ratio for the entire carousel.
Carousel — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "Trip highlights from last weekend",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo1.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo2.jpg"},
{"type": "video", "url": "https://cdn.example.com/clip.mp4"},
{"type": "image", "url": "https://cdn.example.com/photo3.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": True
}
)
print("Carousel posted!", resp.json()["id"]) Carousel — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "Trip highlights from last weekend",
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/photo1.jpg"},
{"type": "image", "url": "https://cdn.example.com/photo2.jpg"},
{"type": "video", "url": "https://cdn.example.com/clip.mp4"},
{"type": "image", "url": "https://cdn.example.com/photo3.jpg"}
],
"platforms": [
{"platform": "instagram", "accountId": "YOUR_ACCOUNT_ID"}
],
"publishNow": true
}' Carousel — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "Trip highlights from last weekend",
mediaItems: [
{ type: "image", url: "https://cdn.example.com/photo1.jpg" },
{ type: "image", url: "https://cdn.example.com/photo2.jpg" },
{ type: "video", url: "https://cdn.example.com/clip.mp4" },
{ type: "image", url: "https://cdn.example.com/photo3.jpg" }
],
platforms: [
{ platform: "instagram", accountId: "YOUR_ACCOUNT_ID" }
],
publishNow: true
})
});
console.log("Carousel posted!", (await resp.json()).id); Story
Set contentType: "story" to publish to Stories. Stories disappear after 24 hours, text captions are not displayed, and link stickers are not available via the API.
Story — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/story.jpg"}
],
"platforms": [{
"platform": "instagram",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
"publishNow": True
}
)
print("Story posted!", resp.json()["id"]) Story — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"mediaItems": [
{"type": "image", "url": "https://cdn.example.com/story.jpg"}
],
"platforms": [{
"platform": "instagram",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "story"
}
}],
"publishNow": true
}' Story — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
mediaItems: [
{ type: "image", url: "https://cdn.example.com/story.jpg" }
],
platforms: [{
platform: "instagram",
accountId: "YOUR_ACCOUNT_ID",
platformSpecificData: {
contentType: "story"
}
}],
publishNow: true
})
});
console.log("Story posted!", (await resp.json()).id); Reel
Set contentType: "reels" to publish a Reel, or let SocialSyncerAPI auto-detect it from vertical 9:16 video under 90 seconds. Reels must be vertical (9:16) and no longer than 90 seconds.
Reel — Python
import httpx
resp = httpx.post(
"https://api.socialsyncerapi.com/v1/posts",
headers={"Authorization": "Bearer sk_your_api_key"},
json={
"content": "New tutorial is up!",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/reel.mp4"}
],
"platforms": [{
"platform": "instagram",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reels",
"shareToFeed": True
}
}],
"publishNow": True
}
)
print("Reel posted!", resp.json()["id"]) Reel — curl
curl -X POST https://api.socialsyncerapi.com/v1/posts \
-H "Authorization: Bearer sk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"content": "New tutorial is up!",
"mediaItems": [
{"type": "video", "url": "https://cdn.example.com/reel.mp4"}
],
"platforms": [{
"platform": "instagram",
"accountId": "YOUR_ACCOUNT_ID",
"platformSpecificData": {
"contentType": "reels",
"shareToFeed": true
}
}],
"publishNow": true
}' Reel — Node.js
const resp = await fetch("https://api.socialsyncerapi.com/v1/posts", {
method: "POST",
headers: {
"Authorization": "Bearer sk_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
content: "New tutorial is up!",
mediaItems: [
{ type: "video", url: "https://cdn.example.com/reel.mp4" }
],
platforms: [{
platform: "instagram",
accountId: "YOUR_ACCOUNT_ID",
platformSpecificData: {
contentType: "reels",
shareToFeed: true
}
}],
publishNow: true
})
});
console.log("Reel posted!", (await resp.json()).id); Media Requirements
Images
- Feed Post: 1 image, JPEG/PNG, max 8 MB, recommended 1080 x 1350 px
- Story: 1 image, JPEG/PNG, max 8 MB, recommended 1080 x 1920 px
- Carousel: Up to 10 images, JPEG/PNG, max 8 MB each, recommended 1080 x 1080 px
Aspect Ratios
- Portrait (4:5): 1080 x 1350 px — Best engagement for feed posts
- Square (1:1): 1080 x 1080 px — Standard feed and carousel
- Landscape (1.91:1): 1080 x 566 px — Widest allowed for feed
- Vertical (9:16): 1080 x 1920 px — Stories and Reels only
Feed posts accept aspect ratios between 0.8 (4:5) and 1.91 (1.91:1). Images outside that range must be posted as Stories or Reels.
Videos
- Feed: MP4/MOV, max 300 MB, max 60 min, aspect 4:5 to 1.91:1, H.264, 30 fps
- Reel: MP4/MOV, max 300 MB, max 90 sec, aspect 9:16, H.264, 30 fps
- Story: MP4/MOV, max 100 MB, max 60 sec, aspect 9:16, H.264, 30 fps
Oversized media is auto-compressed. Images above 8 MB, videos above 300 MB (feed/reels) or 100 MB (stories) are compressed automatically. Original files are preserved.
Platform-Specific Data
All fields go inside platformSpecificData on the Instagram platform entry.
contentType— string — "story" or "reels". Omit for regular feed post. Default: (feed)shareToFeed— boolean — Reel-specific. Set to false to show the Reel in the Reels tab only, not the main feed. Default: truecollaborators— Array of strings — Up to 3 usernames. Must be public Business/Creator accounts. Does not work with Stories.userTags— Array of objects — Tag users in images (not videos). Each has: username (string), x (0.0-1.0), y (0.0-1.0), mediaIndex (optional, 0-based carousel slide).trialParams— object — Trial Reels, shown only to non-followers. graduationStrategy is "MANUAL" or "SS_PERFORMANCE" (auto-graduate if it performs well).thumbOffset— number (ms) — Millisecond offset from video start to use as thumbnail. Ignored if instagramThumbnail is set. Default: 0instagramThumbnail— string (URL) — Custom thumbnail for Reels. JPEG or PNG, recommended 1080 x 1920 px. Takes priority over thumbOffset.audioName— string — Custom audio name for Reels (replaces "Original Audio"). Can only be set at creation.firstComment— string — Auto-posted as the first comment. Works with feed posts and carousels, not Stories. Useful for links since captions do not have clickable links.
Constraints
- Character limit: 2,200 per caption
- Images per post: 1 (feed), 10 (carousel)
- Videos per post: 1
- Daily post limit: 100 posts per 24-hour rolling window
- Video duration: 90 sec (reels), 60 min (feed), 60 sec (story)
- Video size: 300 MB (feed/reels), 100 MB (stories)
- Image size: 8 MB (auto-compressed)
- Collaborators: Max 3 per post
What You Can't Do
These features are not available through Instagram's API:
- Add music to Reels
- Use story stickers (polls, questions, links, countdowns)
- Add location tags
- Go Live
- Create Guides
- Apply filters
- Tag products
- Post to personal accounts (Business or Creator only)
- Create top-level comments (reply-only through the API)
Common Errors
- "Cannot process video from this URL" — A cloud storage sharing link was used instead of a direct media URL. Use a direct CDN URL.
- "You have reached the maximum of 100 posts per day." — Instagram's hard 24-hour rolling limit. Reduce posting volume.
- "Instagram blocked your request." — Automation detection triggered. Reduce posting frequency, vary content.
- "Duplicate content detected." — Identical content was already published recently. Modify the caption or media.
- "Instagram access token expired." — Reconnect the account. Subscribe to the account.disconnected webhook.