What do I need before I can post to Instagram with an API?
Instagram only allows API publishing for Business or Creator accounts that are linked to a Facebook Page. Personal accounts cannot publish through the API. In Socifyr you click Connect on the Instagram integration and approve the Meta consent screen with the Facebook account that manages the Page. That creates a connection with a stable slug such as instagram-mybrand.
Your code then needs only a Socifyr API key and a workspace ID. The Instagram token stays inside Socifyr, so an agent or script that posts for you never holds it. See the Instagram API limits page for the quick reference.
How do I publish a photo or carousel to Instagram?
Send the image URLs (or media library IDs) in medias. One image becomes a single photo post. Two or more become a carousel of up to 10 items, and Instagram carousels can mix photos and video.
curl -X POST https://api.socifyr.com/api/content/photos \
-H "Authorization: Bearer sk_your_key" \
-H "X-Workspace-Id: <workspaceId>" \
-H "Content-Type: application/json" \
-d '{
"connections": ["instagram-mybrand"],
"text": "Behind the scenes at the studio #bts",
"medias": [
"https://cdn.example.com/photo-1.jpg",
"https://cdn.example.com/photo-2.jpg"
],
"contentFormat": "photo_carousel"
}'You can also upload raw files with multipart/form-data (medias[]=@photo.jpg) instead of URLs. The response contains a requestId; poll GET /api/content/status?requestId=... for the per-account result.
How do I post a Reel, a Story or a feed video?
Instagram video has three destinations. Socifyr maps them to a mediaType option, and when you leave it out it derives the destination from contentFormat: story becomes Stories, feed_video becomes a feed video, and anything else becomes a Reel.
| mediaType | Lands as | Notes |
|---|---|---|
REELS | Reel | Default for video. Vertical short video. |
STORIES | Story | Disappears after 24 hours. No caption and no first comment are sent. |
FEED | Feed video | Appears in the main feed. |
import { Socifyr } from '@socifyr/sdk'
const socifyr = new Socifyr({
apiKey: process.env.SOCIFYR_API_KEY!,
workspaceId: process.env.SOCIFYR_WORKSPACE_ID!,
})
await socifyr.uploads.video({
connections: ['instagram-mybrand'],
medias: ['https://cdn.example.com/launch.mp4'],
title: 'Launch day #reels',
platformOptions: {
'instagram-mybrand': { mediaType: 'REELS' },
},
})The Instagram adapter also accepts shareToFeed on Reels and a collaborators list for collab posts. Stories have no comment thread, so a first comment is skipped for them rather than guaranteed to fail.
What are the Instagram API limits for captions, images and video?
| Limit | Value |
|---|---|
| Caption length | 2,200 characters |
| Photo file size | 8 MB per image |
| Photo formats | JPG, PNG |
| Recommended photo size | 1080x1350 |
| Carousel items | Up to 10, photos and video can be mixed |
| Video size and length | 300 MB, 15 minutes |
| Posts per rolling 24 hours | 50 |
| First comment | Supported (not on Stories) |
These numbers come from the shared platform constants Socifyr validates against before publishing. If Instagram rejects a post anyway, the API returns a plain-language reason, for example that the caption is too long for Instagram and the limit is 2,200 characters. Compare every platform in caption length limits per platform.
What aspect ratio does Instagram accept?
Instagram feed images must fall between 4:5 portrait (0.8) and 1.91:1 landscape. Socifyr checks every photo before it goes out. An image inside that range is used as is. A wider image is center-cropped to 1.91:1, and a taller one is center-cropped to 4:5, then re-encoded as a JPEG at quality 92. That means a tall phone screenshot will publish instead of failing, but you lose the top and bottom. If composition matters, crop it yourself first. The full table is in image size and aspect ratio requirements per platform.
How long does an Instagram token last, and what happens when it expires?
Meta issues long-lived tokens that last about 60 days, and Meta tokens cannot be refreshed silently: the adapter's refresh path simply says re-authentication is required. In practice that means refresh_connection will not renew an Instagram account. Socifyr emails a warning 7 days before expiry, and a failed post reports reconnect_required. Use the one-time reconnect link (POST /api/oauth/connections/instagram-mybrand/reconnect-link, socifyr connections reconnect, or the reconnect_connection MCP tool). The owner approves the same account and the slug and scheduled posts keep working. The whole flow is in OAuth token expiry and how to refresh or reconnect accounts.
Can an AI agent post to Instagram for me?
Yes. Add the Socifyr MCP server to Claude, Cursor or ChatGPT and ask it to "post this image to instagram-mybrand as a carousel". The assistant calls post_image with your slug. Set a daily post cap or an approval requirement on the key if you want a human in the loop; see how to give an AI agent safe access to social accounts.
How do I confirm an Instagram post actually went live?
The first response only tells you the post was accepted and queued. It contains a requestId (and an uploadId unless you used async). Instagram publishing runs in the background: the container is created, Socifyr waits for Meta to finish processing it, then publishes. For video that wait can take a while, so poll rather than assume.
const upload = await socifyr.uploads.video({
connections: ['instagram-mybrand'],
medias: ['https://cdn.example.com/launch.mp4'],
title: 'Launch day',
})
const result = await socifyr.uploads.waitForCompletion(upload.id!)
const ig = result.channels.find((c) => c.platform === 'instagram')
console.log(ig?.result?.status, ig?.result?.postUrl, ig?.result?.error)A successful channel carries the post permalink. Stories are the exception: they are ephemeral and have no permalink, so Socifyr does not invent one. If you would rather be pushed than poll, subscribe to the upload.completed, upload.partial_failure or platform.failed webhook events (webhook endpoints are included on the Business plan).
What are the most common Instagram API failures?
- Reconnect needed. The 60-day Meta token expired. Use the reconnect link.
- Account type. The connected account is not a Business or Creator account linked to a Page.
- Caption too long. Anything over 2,200 characters fails. Check length first with
getEffectiveCaptionLimitfrom@socifyr/shared. - File too large. Photos over 8 MB or video over 300 MB. The error lists the platform limits so you know what to compress to.
- Daily cap. More than 50 posts in a rolling 24 hours. Wait for older posts to age out, then retry.
Each failure arrives as a plain-language reason with a next step instead of a raw Graph API error. A failed channel can be retried on its own with uploads.retry(id); channels that already published are skipped.
Frequently asked questions
Can I post to Instagram from a personal account through the API?
How many photos can an Instagram API carousel hold?
Why did my tall image get cropped?
Can I schedule Instagram posts through the API?
scheduledAt to the request. See how to schedule social media posts with an API.