Publish and schedule Instagram photos, Reels and carousels of up to 10 items.
Connecting an account
Instagram needs a professional account (Business or Creator). Personal accounts cannot publish through any API; the user can switch in the Instagram app under Settings → Account type and tools.
The account connects with Instagram sign-in (OAuth). Open Connections in the dashboard, or send a connect link (POST /api/v1/platform-invites with "platform": "instagram", see Connect links). No Facebook page is needed.
An Instagram connection lasts 60 days. FeedHorizon renews it automatically before it runs out, so it keeps working until the user removes FeedHorizon in their Instagram settings. Then the account turns needs_reauth and the account.needs_reauth webhook is sent.
What you can post
| Limit | |
|---|---|
| Text | 2,200 characters |
| Files per post | 1 to 10 files, required |
| Images | JPEG or PNG |
| Videos | MP4 |
| File size | Up to 100 MB by URL import or 5 GB by upload. The platform may refuse large files when publishing |
The post text is the caption.
What gets published depends on the media:
| Media | Published as |
|---|---|
| 1 image | Photo post |
| 1 video | Reel |
| 2 to 10 images or videos | Carousel |
WebP, GIF and MOV files are not accepted for Instagram; convert them first. Instagram also checks aspect ratio and video length when it publishes; a file it rejects fails the target with Instagram's message.
Example
curl -X POST https://feedhorizon.com/api/v1/posts \
-H "Authorization: Bearer fh_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"profileId": "prof_…",
"content": "Three ways to use scheduled exports ↓",
"platforms": ["instagram"],
"mediaIds": ["med_…", "med_…", "med_…"],
"addToQueue": true
}'After publishing
The Instagram target carries the media id in platformPostId and the post's permalink (https://www.instagram.com/p/<shortcode>/) in platformUrl. In the rare case Instagram does not report the permalink, platformUrl stays empty. Videos are processed by Instagram before they go live, so a Reel can take a minute longer than a photo.
Errors
Checked before the post is stored (400, see Error handling):
| Code | Cause | Fix |
|---|---|---|
media_required | No image or video | Add at least one file |
too_many_media | More than 10 files | Remove files or split the post |
media_type_unsupported | For example WebP, GIF or MOV | Convert to JPEG/PNG or MP4 |
content_too_long | Caption over 2,200 characters | Shorten it |
While publishing (in targets[].error, see Publishing errors). Rate limits and outages are retried automatically:
| Code | Cause | Fix |
|---|---|---|
account_needs_reauth | The connection was revoked | Reconnect the account, then retry |
platform_auth_failed | Instagram refused the token or a permission is missing | Reconnect the account, then retry |
platform_rejected | Instagram rejected the media, for example its aspect ratio. error.message has Instagram's reason | Fix the file, then retry |