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 via Facebook Graph API |
| Key precondition | Account must be connected through the Facebook Graph API; connect from VoxBurst Settings → Connected Accounts |
| Re-connect trigger | Token expires after ~60 days; ACCOUNT_DISCONNECTED error signals re-connect needed |
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 |