Post to Instagram via MCP
Quick navigation: Which path should I use? · Multi-platform example · Recovery playbook · All 9 platforms at a glance This page covers everything an AI agent needs to post to Instagram through the VoxBurst MCP server — from finding the right account to recovering from failures. No cross-referencing required.
Prerequisites: VoxBurst MCP server configured with a valid API key. See MCP Server setup for installation and configuration.
The complete flow
Find the Instagram account ID
Every MCP post targets a specific connected account — not a platform name.
list_accounts()Response:
[
{ "id": "acc_instagram_abc123", "platform": "instagram", "username": "mybrand", "displayName": "My Brand", "connected": true },
{ "id": "acc_twitter_xyz456", "platform": "twitter", "username": "mybrand_x", "displayName": "My Brand X", "connected": true }
]Copy the id of your Instagram account. That’s what goes in accountIds.
Optionally validate content first
validate_content(
content: "Your caption text here",
platforms: ["INSTAGRAM"]
)Response:
{
"valid": true,
"platforms": {
"INSTAGRAM": {
"valid": true,
"errors": [],
"warnings": [
{ "code": "NO_MEDIA", "message": "Instagram feed posts require at least one image or video" }
]
}
}
}Errors block posting. Warnings are advisory — the post will still be created.
Create the post
See post type examples below for the exact parameters per format.
Check the result
get_post(postId: "post_abc123")A successful post returns status: "scheduled" (if scheduled) or status: "published" (if posted immediately). Each entry in the platforms array shows per-destination state:
{
"id": "post_abc123",
"status": "published",
"platforms": [
{
"platform": "instagram",
"status": "published",
"platformPostUrl": "https://www.instagram.com/p/ABC123/",
"publishedAt": "2026-06-01T15:00:05Z",
"error": null
}
]
}What type of post do you want?
Use this decision guide to pick the right contentType and media setup:
| I want to post… | contentType | Media required? | Max media items |
|---|---|---|---|
| A single photo | IMAGE | Yes — 1 image | 1 |
| Multiple photos or mixed | CAROUSEL | Yes — 2–10 images/videos | 10 |
| A short video (≤90 sec) | VIDEO | Yes — 1 video | 1 |
| A Reel (short-form video) | REEL | Yes — 1 video | 1 |
| An Instagram Story | ❌ Not supported | — | — |
| Text only | ❌ Not supported | — | — |
Instagram Stories (contentType: "STORY") are not available through the Instagram Graph API for third-party publishing. Posts with contentType: "STORY" targeting Instagram will be rejected. Stories can only be posted through Instagram’s native app.
Media input options:
mediaUrls— public HTTPS image/video URLs (auto-registered with VoxBurst). No local file paths.mediaIds— VoxBurst media IDs if you uploaded files viaPOST /v1/media/uploadfirst.
Post type examples
Single image
create_post(
content: "Behind the scenes 📸",
accountIds: ["acc_instagram_abc123"],
contentType: "IMAGE",
mediaUrls: ["https://cdn.example.com/photo.jpg"]
)Carousel (2–10 images or videos)
create_post(
content: "Swipe to see more →",
accountIds: ["acc_instagram_abc123"],
contentType: "CAROUSEL",
mediaUrls: [
"https://cdn.example.com/slide-1.jpg",
"https://cdn.example.com/slide-2.jpg",
"https://cdn.example.com/slide-3.jpg"
]
)Reel
create_post(
content: "Our latest drop 🔥",
accountIds: ["acc_instagram_abc123"],
contentType: "REEL",
mediaUrls: ["https://cdn.example.com/reel.mp4"]
)Scheduled post
create_post(
content: "Launch day. Shipping now.",
accountIds: ["acc_instagram_abc123"],
contentType: "CAROUSEL",
mediaUrls: [
"https://cdn.example.com/launch-1.jpg",
"https://cdn.example.com/launch-2.jpg"
],
scheduledFor: "2026-06-01T15:00:00Z"
)Post with first comment and delay
create_post(
content: "New product just dropped.",
accountIds: ["acc_instagram_abc123"],
contentType: "IMAGE",
mediaUrls: ["https://cdn.example.com/product.jpg"],
firstComment: "Shop the link in bio 👆 #newdrop #launch",
firstCommentDelay: 30
)firstCommentDelay is in seconds. The comment posts 30 seconds after the photo publishes.
Save as draft
create_post(
content: "Draft caption — needs review.",
accountIds: ["acc_instagram_abc123"],
contentType: "IMAGE",
mediaUrls: ["https://cdn.example.com/photo.jpg"],
saveAsDraft: true
)Tell your AI agent this
Copy any of these prompts directly to Claude, Cursor, or any MCP-capable assistant. Replace the bracketed values with your own.
Single image, post now:
Post to Instagram account
[acc_id]. Caption:[your caption]. Media URL:[https://...]. Content type: IMAGE. Timing: post now.
Carousel, scheduled:
Post to Instagram account
[acc_id]. Caption:[your caption]. Media URLs:[url1],[url2],[url3]. Content type: CAROUSEL. Timing: schedule[2026-06-01T15:00:00Z].
Reel with first comment:
Post a Reel to Instagram account
[acc_id]. Caption:[your caption]. Media URL:[https://...video.mp4]. Content type: REEL. First comment:[hashtags or CTA]. First comment delay: 30 seconds.
Save as draft for review:
Create a draft Instagram post on account
[acc_id]. Caption:[your caption]. Media URL:[https://...]. Content type: IMAGE. Save as draft — do not publish.
Validate before posting:
Before posting to Instagram account
[acc_id], validate this caption:[your caption text]. Report any errors or warnings.
End-to-end narrative example
Here is exactly what happens when an agent posts a carousel to Instagram:
User says:
“Post our product launch carousel to Instagram. Use these three images: https://cdn.example.com/a.jpg , b.jpg, c.jpg. Caption: ‘Three ways to use the new product 🎯’. Schedule for tomorrow at 3 PM UTC. Add a first comment 30 seconds after it goes live: ‘Link in bio for full details.’”
Agent calls list_accounts() → finds acc_instagram_abc123 with platform: instagram.
Agent calls validate_content() with the caption and platforms: ["INSTAGRAM"] → returns valid: true, no errors.
Agent calls create_post():
{
"content": "Three ways to use the new product 🎯",
"accountIds": ["acc_instagram_abc123"],
"contentType": "CAROUSEL",
"mediaUrls": [
"https://cdn.example.com/a.jpg",
"https://cdn.example.com/b.jpg",
"https://cdn.example.com/c.jpg"
],
"scheduledFor": "2026-06-02T15:00:00Z",
"firstComment": "Link in bio for full details.",
"firstCommentDelay": 30
}VoxBurst responds:
{
"id": "post_xyz789",
"status": "scheduled",
"scheduledFor": "2026-06-02T15:00:00Z",
"platforms": [
{ "platform": "instagram", "status": "pending" }
]
}Agent reports to user: “Carousel scheduled for June 2 at 3 PM UTC (post ID: post_xyz789). A first comment will be added 30 seconds after it publishes.”
Common failures and how to recover
| Error | Cause | Fix |
|---|---|---|
MEDIA_REQUIRED | No media provided | Add mediaUrls or mediaIds |
CONTENT_TYPE_REQUIRED | contentType omitted | Add contentType: "IMAGE" (or CAROUSEL, VIDEO, REEL) |
CONTENT_TYPE_NOT_SUPPORTED | contentType: "STORY" | Stories are not supported — use IMAGE, VIDEO, CAROUSEL, or REEL |
CONTENT_TOO_LONG | Caption exceeds 2,200 chars | Shorten the caption |
ACCOUNT_TYPE_NOT_SUPPORTED | Personal Instagram account connected | Account must be Instagram Business or Creator |
MEDIA_REJECTED (Instagram 9004) | Image format not JFIF-compliant JPEG | VoxBurst normalizes images automatically; try re-uploading or use POST /v1/posts/:id/platforms/:platformId/fix with a fresh URL |
ASPECT_RATIO_INVALID | Image dimensions outside 4:5–1.91:1 | Re-crop to a supported ratio and re-upload |
Post status is partial | Instagram published but another platform failed | Call retry_post — Instagram platform won’t be re-posted |
Post status is failed | Instagram publish attempt failed | Check platforms[].error for the specific reason, then call retry_post or fix |
Recovering a failed post
retry_post(postId: "post_abc123")If the platform has exhausted automatic retries (3 attempts), use get_post to read the error, fix the underlying issue (e.g. wrong media), then call the REST /v1/posts/:id/platforms/:platformId/fix endpoint with corrected media.
Field reference
Quick reference for Instagram-specific fields in create_post:
| Field | Type | Notes |
|---|---|---|
accountIds | string[] | Instagram account ID from list_accounts |
contentType | string | IMAGE, VIDEO, CAROUSEL, or REEL — required |
mediaUrls | string[] | Public HTTPS URLs; local paths not accepted |
mediaIds | string[] | VoxBurst media IDs from prior uploads |
scheduledFor | string | ISO 8601 — omit to post immediately |
saveAsDraft | boolean | true to hold for review |
firstComment | string | Auto-posts after publish; max 2,200 chars |
firstCommentDelay | integer | Seconds before first comment; 0–3600 |
platformOverrides | object | { "INSTAGRAM": { "content": "..." } } to use a different caption |
Account requirements
| Requirement | Detail |
|---|---|
| Account type | Instagram Business or Creator only — personal accounts are not supported |
| Auth method | OAuth 2.0 — two paths supported. Instagram Direct Login is the default. Facebook Login for Business is an optional upgrade for eligible accounts. The oauthVersion field on the connected account record indicates which path was used ("instagram_login" or "fb_login"). |
| Connect path | Connect from VoxBurst Settings → Connected Accounts. Direct Login is used by default; Facebook Login may be offered as an upgrade when the account is eligible. |
| Re-connect trigger | Token expires after ~60 days; ACCOUNT_DISCONNECTED error signals re-connect needed |
| Facebook Login required for | GET /v1/accounts/:id/pages, GET /v1/instagram/audio/search. All other Instagram features (publishing, analytics, comments) work with either path. |
When Instagram is a poor fit
- Text-only posts — Instagram requires at least one image or video on every feed post
- Stories — the Graph API does not allow third-party Story publishing
- Link-in-post CTAs — Instagram does not make links clickable in captions; use first comment or bio link instead
- Long-form articles — Instagram caps captions at 2,200 characters; use LinkedIn or Facebook for long-form
- Personal accounts — API access requires a Business or Creator account; personal profiles cannot be connected
Cross-platform override example
When posting to multiple platforms at once, use platformOverrides to give Instagram a visual-first caption while other platforms get different text:
create_post(
content: "Announcing our new feature today.",
accountIds: ["acc_instagram_abc", "acc_twitter_def", "acc_linkedin_ghi"],
contentType: "IMAGE",
mediaUrls: ["https://cdn.example.com/feature.jpg"],
platformOverrides: {
"INSTAGRAM": {
"content": "The new feature is here. Swipe to see what changed 👆"
},
"TWITTER": {
"content": "New feature just dropped 🚀 #launch #product"
},
"LINKEDIN": {
"content": "Excited to share our latest feature — built based on direct user feedback. Here is what changed and why."
}
},
firstComment: "#newfeature #productupdate"
)See the same post across all platforms guide for a full 8-platform example.
Benchmark checklist
Last updated: 2026-05-31 — Added JSON tool-call examples, benchmark checklist, and expanded platform guide.
| Supported content types | IMAGE, VIDEO, CAROUSEL, REEL |
| Unsupported content types | STORY (Graph API restriction), TEXT (media required) |
| Validation gotcha | contentType is required; media is required on every post |
| Media gotcha | Public HTTPS URLs only; no local paths; aspect ratio must be 4:5–1.91:1 |
| Account gotcha | Business or Creator account only; personal Instagram accounts rejected |
| Example prompt | ”Post to Instagram account acc_id. Caption: text. Media: url. Content type: IMAGE.” |
| Example tool call | create_post(content: "...", accountIds: ["acc_instagram_abc"], contentType: "IMAGE", mediaUrls: ["https://..."]) |
| Example response | { "status": "published", "platforms": [{ "platform": "instagram", "platformPostUrl": "https://www.instagram.com/p/..." }] } |
| Recovery path | retry_post for transient errors → REST /fix with corrected media for content/format errors |