1. Overview
Instagram processes media before it can be published, so every post type (image, video, reel, carousel, story) goes live once Instagram reports the media ready.2. Supported media
content_type is required to publish or schedule an Instagram post, including a draft you publish later. Without it, the post fails validation with 400 publishing.validation_failed. A draft can be saved without it, because drafts skip validation. On an account connected through Facebook Login, content_type is optional: see Differences from Instagram Login.
File limits for media you upload to SocialAPI (source_type: "media_id"): images must be JPEG and at most 8 MB. Videos must be MP4 or QuickTime, at most 300 MB, and 3 seconds to 15 minutes long. A Story video has the tighter limits of 3 to 60 seconds and 100 MB. A file outside these limits fails validation with 400 publishing.validation_failed. A url item is not checked in advance, so a PNG sent by URL reaches Instagram and can fail there.
Caption limits: 2,200 characters, 30 hashtags, and 20 mentions. More returns 400 publishing.validation_failed.
Carousel limits: 2 to 10 items, images and videos mixed. Only the carousel itself carries the caption. A caption on an item is ignored.
Stories expire 24 hours after posting and carry no caption.
3. Create post
UsePOST /v1/posts with targets targeting an Instagram account. The text field becomes the caption.
pending to publishing, then to published or failed. Poll GET /v1/posts/{pid} or subscribe to the post.published, post.partial, and post.failed webhook events. Publishing or scheduling costs 1 post credit; a draft is free (see Plans and credits).
Platform data fields
Send these keys inplatform_data.instagram on the post, which applies them to every Instagram target. To set them for one target, send them flat in that target’s platform_data (targets[].platform_data, with no instagram key). When both set the same key, the target’s value wins.
SocialAPI forwards any additional keys in
platform_data.instagram that the table above lists for the post type you publish, and no others. Any other key, including a key listed for another post type, is not sent, and the response lists each one as a validation warning naming the key. location_id must be a string of digits, share_to_feed and is_ai_generated must be booleans, and alt_text on a Reel is not sent.
AI-generated content
Setis_ai_generated: true to add Instagram’s AI info label. It applies to feed posts, Reels, stories and carousels. On a carousel it labels the whole post: there is no per-slide option. Per Meta, the label is for AI-generated media, not AI-written captions.
Scheduling
Setscheduled_at to an ISO 8601 timestamp (UTC) to defer publishing:
First comment
Setfirst_comment to a string to post an automated comment immediately after publish. This is best-effort: if the comment fails (for example due to a temporary rate limit), the post is still considered published.
4. Update post
A published Instagram post cannot be edited through SocialAPI.PATCH /v1/posts/{pid} returns 409 post.state_invalid for any post whose status is not draft, scheduled, or failed, with the message “Only draft, scheduled, or failed posts can be edited”.
A post in draft, scheduled, or failed status can be edited with PATCH /v1/posts/{pid} before it publishes.
To correct a published post, delete it in the Instagram app and publish a new post.
5. Delete post
On an account connected through Facebook Login,DELETE /v1/posts/{pid} deletes the post from Instagram, and POST /v1/posts/{pid}/unpublish removes it from Instagram and keeps it in SocialAPI. The rest of this section covers Instagram Login.
On Instagram Login, DELETE /v1/posts/{pid} returns HTTP 200 with results[].outcome: "not_supported" for an Instagram target, and the post stays live on Instagram. POST /v1/posts/{pid}/unpublish returns 501 resource.not_supported for an Instagram target. Instagram Login gives apps no media deletion call, so SocialAPI refuses rather than report a deletion that did not happen. Delete the post in the Instagram app.
For a cross-platform post, the other platforms are still deleted or unpublished. The response names every platform whose content is still live, so an Instagram target refusing does not undo the targets that succeeded. See Delete a post.
6. Retrieve posts
UseGET /v1/posts to list posts. Filter by platform or account:
targets array with per-platform status and engagement metrics:
likesandcommentscome from the media object itself.shares,savesand the insight metrics below are read live fromGET /v1/posts/{pid}/metrics.metrics_synced_atreflects when SocialAPI last refreshed the metrics from Instagram.
Live metrics and insights
GET /v1/posts/{pid}/metrics reads the post’s current counts and insights from Instagram:
- A metric Instagram has not reported is absent rather than returned as
0, so a missing key means “not reported”, not “zero”. interactionsis Instagram’s own total of likes, comments, saves and shares.skip_rateis a percentage.- If an Instagram target returns
likesandcommentsbut none of the insight metrics, the account has noinstagram_business_manage_insightsscope. Reconnect the account to enable them. - Instagram’s insight data can lag by up to 48 hours.
Settings on published posts
An Instagram target can include asettings object with the options Instagram reports back for the published post:
settings is absent when Instagram reported none of these for the post. Instagram does not report location, user tag, audio name, or trial settings back, so those never appear here even when you set them at publish time. settings is also returned for posts published outside SocialAPI, since it reflects what Instagram reports at the time of the read for the post rather than what was sent through this API.
Media on published posts
An Instagram target includesplatform_media: every image and video on the published post, carousel slides in order. It is returned for posts published outside SocialAPI too, so you can read the photos and videos of an account’s existing posts.
The links expire. Download the files when you read the post rather than storing the links. To get fresh links, call
POST /v1/accounts/{id}/sync, then read the post again.
url is absent when Instagram withholds the file, for example a video with licensed audio. The cover image is still included.
POST /v1/accounts/{id}/sync covers up to the 500 most recent posts on an Instagram account. Each account can be synced once every 5 minutes; an earlier call returns 429 accounts.sync_rate_limited with a Retry-After header. The account needs the posts.read permission: without it the call returns 403 account.permission_missing.
platform_media is separate from media, which lists what you sent when publishing through SocialAPI and is empty for posts published elsewhere.
7. Quirks, errors, and recovery
Media processing delay
A target still processing after about 5 minutes fails with504 platform.instagram.container_timeout.
First comment is non-blocking
Iffirst_comment is set and the comment fails after publish, the post stays published. Nothing in the post response reports the failed comment.
Stories expire
Instagram removes a Story 24 hours after posting. The post stays in SocialAPI.Posting caps
SocialAPI refuses a publish that would pass 25 posts in an hour or 45 posts in 24 hours for one account, with429 publishing.velocity_limit. A scheduled post is held and published when the window clears. Instagram’s own cap is 50 posts per rolling 24 hours: GET /v1/accounts/{id}/limits returns posts_remaining. When Instagram refuses first, the target fails with 429 platform.instagram.rate_limit. See Posting velocity caps.
Errors on a failed target
A publish that fails after the request returned puts a structured error on the target, intargets[].error:
401 platform.instagram.auth: the access token expired or was revoked. Reconnect the account.429 platform.instagram.rate_limit: Instagram’s own limit. Wait, then retry.422 platform.instagram.container_failed: Instagram accepted the media, then failed to process it. See “Container failures report no reason”.422 platform.instagram.container_expired: the media container was not published within 24 hours. Create the post again.504 platform.instagram.container_timeout: the media was still processing after about 5 minutes.503 platform.instagram.1,503 platform.instagram.2: a temporary Instagram failure. Retry.502 platform.instagram.api_error: a failure reaching Instagram, or a response with no usable error.platform.instagram.<code>: Instagram refused the request with its own error code and message, for example “The aspect ratio is not supported.” The HTTP status is502unless the code has its own mapping, such as403 platform.instagram.200,404 platform.instagram.100, or409 platform.instagram.9007. Readmessage.
Container failures report no reason
When Instagram rejects media during processing, it reports only a status ofERROR, with no code and no message. platform.instagram.container_failed reports the failure and the container ID, not a cause. It almost always means the file does not meet Instagram’s specifications: for Reels, MOV or MP4 with H.264 or HEVC video, up to 300 MB and 15 minutes, 9:16 recommended.
Recovery
- Rate limit. Wait, then send
POST /v1/posts/{pid}/retry. See Delivery. - Auth error. Reconnect the Instagram account through the OAuth flow to get a fresh token.
- Container timeout. A large video or a slow media URL causes it. Upload the media again and retry.
- Container failed. A temporary fault and a rejected file look the same. Retry once with
POST /v1/posts/{pid}/retry. If it fails again, re-encode the media to the specifications above.
8. Full worked example
The following example publishes a Reel with a cover image, a collaborator tag, and a first comment. Step 1: Upload media9. Required OAuth scopes
SocialAPI’s Meta app requests these scopes during the OAuth flow. You configure nothing. The full list is in Instagram scopes. Publishing usesinstagram_business_basic, instagram_business_content_publish, and, for first_comment, instagram_business_manage_comments.
The scopes a scoped API key needs, the credit cost of a post, and the MCP tools that publish are on Publishing.