Instagram API
Postproxy publishes feed posts, Reels, and Stories to an Instagram professional (Business or Creator) account, and lets you read and reply to comments and read and send direct messages — including private replies to commenters and inbound story mentions.
Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.
Profiles and profile groups
Section titled “Profiles and profile groups”Every post targets one or more profiles. A profile is one connected account — for Instagram, an Instagram Business or Creator account. Reference one in a request by its id (the prof_abc123 in the examples below) or by the platform name "instagram", which selects the group’s Instagram profile (a group holds at most one profile per platform). List what’s connected with GET /api/profiles.
Profiles live in profile groups — containers that organize the accounts for one brand, client, or project. List groups with GET /api/profile_groups, and connect a new Instagram profile with the Initialize Connection endpoint.
Example: get profiles and profile groups
List the profiles you can post to — GET /api/profiles:
curl -X GET "https://api.postproxy.dev/api/profiles" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "prof_abc123", "name": "@mycompany", "platform": "instagram", "status": "active", "profile_group_id": "grp_xyz789", "expires_at": null, "post_count": 96, "avatar_url": "https://cdn.postproxy.dev/uploads/avatar_prof_abc123.jpg" } ]}List your profile groups — GET /api/profile_groups:
curl -X GET "https://api.postproxy.dev/api/profile_groups" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "grp_xyz789", "name": "Main Brand", "profiles_count": 5 }, { "id": "grp_def456", "name": "Client Project", "profiles_count": 3 } ]}At a glance
Section titled “At a glance”| Platform ID | instagram |
| Formats | post (default), reel, story |
| Character limit | 2,200 (Stories have no caption) |
| Media | Required on every format |
| Comments | List, reply, delete, hide/unhide |
| Direct messages | Yes — text, media, reactions, private replies, ice breakers, ig.me referrals |
| Post chains | No |
Publishing
Section titled “Publishing”Formats
Section titled “Formats”| Format | Description |
|---|---|
post | Feed post — single image, video, or carousel (default) |
reel | Instagram Reel |
story | Instagram Story |
Feed post
Section titled “Feed post”| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | No | "post" (default) |
first_comment | string | No | Comment added after publishing (max 2,196 characters) |
collaborators | array | No | Collaborator usernames to invite |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Image | 8 MB | jpg, png | 10 | — |
| Video | 300 MB | mp4, mov | 1 | 3 s – 60 min |
- Media is required. Text caption is optional.
- Pass 2–10 media items in
mediato publish a carousel; a single item posts as a regular photo or video. - Images and a video can be mixed in one carousel.
- Minimum image dimensions: 200×200 px.
# Feed carousel with a first comment and collaboratorscurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Three takeaways from our launch week 👇" }, "profiles": ["prof_abc123"], "media": [ "https://example.com/slide1.jpg", "https://example.com/slide2.jpg", "https://example.com/slide3.jpg" ], "platforms": { "instagram": { "format": "post", "first_comment": "Follow for more content!", "collaborators": ["partnerhandle"] } } }'| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | Yes | "reel" |
first_comment | string | No | Comment added after publishing (max 2,196 characters) |
cover_url / cover_file | string / file | No | Cover image. Pass cover_url (URL) in JSON or cover_file (file) in multipart |
audio_name | string | No | Name of the audio track |
trial_strategy | string | No | Trial-reel strategy: "MANUAL" or "SS_PERFORMANCE" |
collaborators | array | No | Up to 3 collaborator usernames |
thumb_offset | string | No | Thumbnail offset in milliseconds. Ignored if cover_url is set |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Video | 300 MB | mp4, mov | 1 | 3 s – 90 min |
- A video is required; images are not accepted on Reels.
# Reel with a cover image and audio namecurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "New reel is live! Full tutorial on our channel 🎬" }, "profiles": ["prof_abc123"], "media": ["https://example.com/video.mp4"], "platforms": { "instagram": { "format": "reel", "first_comment": "Full tutorial link in bio!", "cover_url": "https://example.com/thumbnail.jpg", "audio_name": "Trending Audio Track" } } }'| Parameter | Type | Required | Description |
|---|---|---|---|
format | string | Yes | "story" |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Image | 8 MB | jpg, png | 1 | — |
| Video | 100 MB | mp4, mov | 1 | 1 s – 60 min |
- Media is required; text captions are not supported.
- Minimum dimensions: 200×200 px.
# Story (single image)curl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": {}, "profiles": ["prof_abc123"], "media": ["https://example.com/story.jpg"], "platforms": { "instagram": { "format": "story" } } }'Rate limits
Section titled “Rate limits”- 100 posts per day per user, on a rolling 24-hour window, across all Instagram formats.
- Instagram may also throttle bursts with
User is performing too many actions. Slow down and retry later when you hit it.
Comments
Section titled “Comments”Instagram comments are managed through the Comments API. All comment writes are asynchronous. Every call needs the profile_id query parameter.
| Action | Supported |
|---|---|
| List / read | Yes |
| Reply | Yes |
| Delete | Yes |
| Hide / unhide | Yes |
| Like / unlike | No |
- Comments are text-only — the
attachmentsarray is always empty. - Author metadata is available when Instagram returns it:
is_verified_user,is_user_follow_business,is_business_follow_user, andfollower_count. - A
comment.createdwebhook fires when a new comment is synced.
# List comments on a postcurl "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"# Reply to a comment (omit parent_id to comment on the post itself)curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Thanks for the kind words!", "parent_id": "cmt_abc123" }'# Hide / unhide a commentcurl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/hide?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"
curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/unhide?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"# Delete a commentcurl -X DELETE "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"Direct messages
Section titled “Direct messages”Instagram Direct is supported through the Direct Messages API. Outbound sends are asynchronous and accept either text or a single attachment per send.
| Capability | Supported |
|---|---|
| Send / receive text | Yes |
| Attachments | Yes — one per send |
| Reactions | Yes — Instagram accepts love (an emoji may accompany it) |
| Edit outbound message | No |
| Delivery / read receipts | Yes |
| Private reply to a comment | Yes |
| ig.me link referrals | Yes |
| Ice breakers | Yes — up to 4 questions |
| Inbound delivery | Webhook |
- 24-hour window. Free-form messages are only allowed within 24 hours of the participant’s last message. Sending outside the window is not supported.
- Private replies DM a commenter directly, bypass the 24-hour window (up to 7 days after the comment), and are allowed once per comment.
- Story mentions arrive as inbound messages with a
story_mentionattachment, mirrored to durable storage. Story replies populatestory_replyon the message. - ig.me link referrals. When a user enters the thread via
https://ig.me/m/<username>?ref=..., the referral is stored on the chat (metadata.referral), areferral.receivedwebhook fires, and the 24-hour window opens — you can reply before the user sends a message. Meta only delivers ig.me referrals for profiles with at least one ice breaker set. - Ice breakers. Manage the up to four suggested questions shown when a user opens a new thread, via
GET/POST/DELETE /api/profiles/:id/ice_breakers. A tap arrives as an inbound message carrying yourpayloadunderplatform_data.postback.payload. - Start a chat with the participant’s Instagram-scoped user ID as
participant_external_id.
# List chats for the profilecurl "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \ -H "Authorization: Bearer YOUR_API_KEY"# Create or find a chat by participant ID (idempotent)curl -X POST "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "participant_external_id": "17841400000000000", "participant_username": "janedoe" }'# Send a text messagecurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Hi! Thanks for reaching out 👋" }'# Send a single media attachmentcurl -X POST "https://api.postproxy.dev/api/chats/chat_abc123/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "media": ["https://example.com/catalog.jpg"] }'# React to a message (Instagram accepts "love")curl -X POST "https://api.postproxy.dev/api/messages/msg_abc123/react" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reaction": "love" }'# Private reply to a commenter (bypasses the 24h window, once per comment)curl -X POST "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123/private_reply?profile_id=prof_abc123" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "text": "Just sent you a DM with the details!" }'# Set ice breakers (replaces the existing set)curl -X POST "https://api.postproxy.dev/api/profiles/prof_abc123/ice_breakers" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ice_breakers": [ { "question": "Track my order", "payload": "TRACK_ORDER" }, { "question": "What are your hours?", "payload": "HOURS" } ] }'Postproxy records periodic stat snapshots you can pull as a timeseries; field names pass through from Instagram unchanged.
Profile stats
Section titled “Profile stats”Account-level metrics, refreshed roughly every 23 hours via the Profile stats endpoint (GET /api/profiles/:id/stats).
Fields: followers_count, follows_count, media_count, plus per-window insights suffixed _1d, _7d, _14d, _30d (reach_*, profile_views_*, accounts_engaged_*, total_interactions_*, website_clicks_*, follower_count_*)
# Fetch the profile stats timeseriescurl "https://api.postproxy.dev/api/profiles/prof_abc123/stats" \ -H "Authorization: Bearer YOUR_API_KEY"Post stats
Section titled “Post stats”Per-post engagement, captured after publish via the Post stats endpoint (GET /api/posts/stats).
Fields: impressions, likes, comments, saved, profile_visits, follows
Stories do not return post stats.
# Fetch post statscurl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123&profiles=instagram" \ -H "Authorization: Bearer YOUR_API_KEY"Webhooks
Section titled “Webhooks”Subscribe with the Webhooks API. Create a subscription:
curl -X POST "https://api.postproxy.dev/api/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/postproxy", "events": ["platform_post.published", "comment.created", "message.received"] }'Events relevant to Instagram:
| Event | When |
|---|---|
post.processed | A post is ready to publish |
platform_post.published | A post was published to the platform |
platform_post.failed | A post failed to publish (retries exhausted) |
platform_post.failed_waiting_for_retry | A publish attempt failed; will retry |
platform_post.insights | New analytics snapshot |
comment.created | A comment was synced on an Instagram post |
message.received / .sent | Inbound / outbound DM |
message.delivered / .read | Delivery and read receipts |
message.deleted | A message was unsent (Instagram is the only network that reports this) |
message.edited | An inbound message was edited |
reaction.received | A reaction was added or removed on a message |
referral.received | A participant entered a DM thread via an ig.me link |
profile.connected / .disconnected | Connection state changed |
profile.stats | New profile stats snapshot |
media.failed | A media attachment failed to process |
- Only professional (Business or Creator) Instagram accounts can publish via the API.
- Carousels may combine images and a video; Reels and Stories are single-media.
- Trial Reels (
trial_strategy) publish to non-followers first; useMANUALorSS_PERFORMANCE.