1. Overview
Instagram publishing uses the Meta Graph API two-step flow: SocialAPI creates a media container, polls until the container is ready, then publishes it. All post types (image, video, reel, carousel, story) go through this same pipeline.| Field | Value |
|---|---|
| Platform slug | instagram |
| Auth type | OAuth 2.0 (Meta) |
| API | Meta Graph API |
| Create post | Yes |
| Update post | No (not supported by platform) |
| Delete post | Yes |
| Schedule | Yes (deferred publish via schedule_at) |
| First comment | Yes (best-effort, non-blocking) |
2. Supported media
| Content type | How to trigger | Notes |
|---|---|---|
| Single image | platform_data.instagram.content_type: "feed" or omit with one media_ids entry | Standard image post |
| Single video (Reel) | URL ending in .mp4, .mov, etc., or content_type: "reel" | Published as media_type: REELS |
| Carousel | Two or more media_ids entries, or content_type: "carousel" | 2 to 10 items; mix of images and videos allowed |
| Story | platform_data.instagram.content_type: "stories" | Single image or video; captions not supported |
content_type is omitted, SocialAPI auto-detects: multiple media_ids produce a carousel, a single entry produces a feed image or reel depending on file extension.
Story publishing is supported via the API using content_type: "stories". Note that stories expire after 24 hours and the Instagram platform does not support captions on stories.
Caption limit: 2200 characters.
Carousel limits: 2 to 10 items. Carousel child containers do not accept captions; only the parent container carries the caption.
3. Create post
UsePOST /v1/posts with account_ids targeting an Instagram account. The text field becomes the caption.
Platform data fields
Pass these insideplatform_data.instagram:
| Field | Type | Description |
|---|---|---|
content_type | string | One of "feed", "reel", "carousel", "stories". Overrides auto-detection. |
alt_text | string | Accessibility alt text applied to the image container. |
location_id | string | Facebook location page ID to geo-tag the post. |
share_to_feed | bool | For Reels, also share to the main profile feed. |
cover_url | string | Custom cover image URL for video or Reel posts. |
collaborators | string or array | Instagram usernames to tag as collaborators. Leading @ is stripped automatically. Accepts a single string, a comma-separated string, or a JSON array. |
video_cover_timestamp_ms | number | Millisecond offset into the video to use as the cover frame. Ignored if cover_url is set. |
platform_data.instagram directly to the underlying platform API. These fields are not validated by SocialAPI and may break if the platform changes its API. See Instagram Publishing API reference for the full list of supported parameters.
Scheduling
Setschedule_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
Instagram does not support editing a published post’s caption or media via the API.PATCH /v1/posts/:pid for an Instagram target returns 501 Not Implemented.
If you need to correct a caption, delete the post and recreate it.
5. Delete post
DELETE /{ig-media-id} on the Meta Graph API. If the media ID no longer exists on Instagram, the API returns success.
6. Retrieve posts
UseGET /v1/posts to list posts. Filter by platform or account:
targets array with per-platform status and engagement metrics:
likes,comments, andsharesare synced periodically from the Meta Graph API.savesis not available from the Instagram API and is always0.sharesis typically0for Instagram (the platform does not expose a public share count).metrics_synced_atreflects when SocialAPI last refreshed the metrics from Instagram.
7. Quirks, errors, and recovery
Container polling
After creating a media container, SocialAPI polls the container status before publishing. Instagram processes images almost instantly, but videos and reels can take up to 60 seconds (12 attempts at 5-second intervals). If the container does not reachFINISHED within that window, the publish fails with 504 Gateway Timeout and the post target is marked failed.
Because presigned S3 URLs do not reliably expose file extensions in the path, SocialAPI polls all containers unconditionally, not only video ones.
Carousel captions
Only the parent carousel container accepts a caption. Child item containers are created without captions. Passing a caption on a carousel child is silently ignored by the Meta Graph API; SocialAPI does not forward captions to child containers.First comment is non-blocking
Iffirst_comment is set and the comment fails after publish, the post remains published. The comment failure is logged but does not roll back or change the post status.
Stories expire
Instagram Stories expire 24 hours after posting. The post record in SocialAPI is not automatically removed when the story expires on Instagram.Error shapes
When a publish fails, the post target’serror field contains a structured error:
| Error code | Category | Caused by | Meaning |
|---|---|---|---|
platform.instagram.api_error | platform | platform | Meta Graph API rejected the request. Check message for details. |
platform.instagram.rate_limit | rate_limit | platform | Instagram rate limit hit. Retry after a delay. |
platform.instagram.auth | auth | platform | Access token expired or revoked. Reconnect the account. |
Recovery
- Rate limit: Retry the post via
POST /v1/posts/:pid/retryafter waiting. SocialAPI applies exponential backoff for scheduled retries. - Auth error: Disconnect and reconnect the Instagram account through the OAuth flow to obtain a fresh token.
- Container timeout: Usually caused by a large video file or a slow upstream URL. Re-upload the media and retry.
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
The following Meta app scopes must be approved for your application before publishing will work:| Scope | Purpose |
|---|---|
instagram_business_basic | Read basic account info and media |
instagram_business_manage_comments | Post and manage comments (required for first comment) |
instagram_business_manage_messages | Send and receive DMs |
instagram_business_content_publish | Create and publish media containers |
400 or 403 from the Meta Graph API.
To verify which scopes your connected account has, call GET /v1/accounts/:id/limits.