Skip to content

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.

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:

Terminal window
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:

Terminal window
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 }
]
}
Platform IDinstagram
Formatspost (default), reel, story
Character limit2,200 (Stories have no caption)
MediaRequired on every format
CommentsList, reply, delete, hide/unhide
Direct messagesYes — text, media, reactions, private replies, ice breakers, ig.me referrals
Post chainsNo
FormatDescription
postFeed post — single image, video, or carousel (default)
reelInstagram Reel
storyInstagram Story
ParameterTypeRequiredDescription
formatstringNo"post" (default)
first_commentstringNoComment added after publishing (max 2,196 characters)
collaboratorsarrayNoCollaborator usernames to invite
MediaMax sizeFormatsCountDuration
Image8 MBjpg, png10
Video300 MBmp4, mov13 s – 60 min
  • Media is required. Text caption is optional.
  • Pass 2–10 media items in media to 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.
Terminal window
# Feed carousel with a first comment and collaborators
curl -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"]
}
}
}'
ParameterTypeRequiredDescription
formatstringYes"reel"
first_commentstringNoComment added after publishing (max 2,196 characters)
cover_url / cover_filestring / fileNoCover image. Pass cover_url (URL) in JSON or cover_file (file) in multipart
audio_namestringNoName of the audio track
trial_strategystringNoTrial-reel strategy: "MANUAL" or "SS_PERFORMANCE"
collaboratorsarrayNoUp to 3 collaborator usernames
thumb_offsetstringNoThumbnail offset in milliseconds. Ignored if cover_url is set
MediaMax sizeFormatsCountDuration
Video300 MBmp4, mov13 s – 90 min
  • A video is required; images are not accepted on Reels.
Terminal window
# Reel with a cover image and audio name
curl -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"
}
}
}'
ParameterTypeRequiredDescription
formatstringYes"story"
MediaMax sizeFormatsCountDuration
Image8 MBjpg, png1
Video100 MBmp4, mov11 s – 60 min
  • Media is required; text captions are not supported.
  • Minimum dimensions: 200×200 px.
Terminal window
# 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" } }
}'
  • 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.

Instagram comments are managed through the Comments API. All comment writes are asynchronous. Every call needs the profile_id query parameter.

ActionSupported
List / readYes
ReplyYes
DeleteYes
Hide / unhideYes
Like / unlikeNo
  • Comments are text-only — the attachments array is always empty.
  • Author metadata is available when Instagram returns it: is_verified_user, is_user_follow_business, is_business_follow_user, and follower_count.
  • A comment.created webhook fires when a new comment is synced.
Terminal window
# List comments on a post
curl "https://api.postproxy.dev/api/posts/post_abc123/comments?profile_id=prof_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"
Terminal window
# 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" }'
Terminal window
# Hide / unhide a comment
curl -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"
Terminal window
# Delete a comment
curl -X DELETE "https://api.postproxy.dev/api/posts/post_abc123/comments/cmt_abc123?profile_id=prof_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"

Instagram Direct is supported through the Direct Messages API. Outbound sends are asynchronous and accept either text or a single attachment per send.

CapabilitySupported
Send / receive textYes
AttachmentsYes — one per send
ReactionsYes — Instagram accepts love (an emoji may accompany it)
Edit outbound messageNo
Delivery / read receiptsYes
Private reply to a commentYes
ig.me link referralsYes
Ice breakersYes — up to 4 questions
Inbound deliveryWebhook
  • 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_mention attachment, mirrored to durable storage. Story replies populate story_reply on 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), a referral.received webhook 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 your payload under platform_data.postback.payload.
  • Start a chat with the participant’s Instagram-scoped user ID as participant_external_id.
Terminal window
# List chats for the profile
curl "https://api.postproxy.dev/api/profiles/prof_abc123/chats" \
-H "Authorization: Bearer YOUR_API_KEY"
Terminal window
# 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" }'
Terminal window
# Send a text message
curl -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 👋" }'
Terminal window
# Send a single media attachment
curl -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"] }'
Terminal window
# 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" }'
Terminal window
# 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!" }'
Terminal window
# 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.

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_*)

Terminal window
# Fetch the profile stats timeseries
curl "https://api.postproxy.dev/api/profiles/prof_abc123/stats" \
-H "Authorization: Bearer YOUR_API_KEY"

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.

Terminal window
# Fetch post stats
curl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123&profiles=instagram" \
-H "Authorization: Bearer YOUR_API_KEY"

Subscribe with the Webhooks API. Create a subscription:

Terminal window
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:

EventWhen
post.processedA post is ready to publish
platform_post.publishedA post was published to the platform
platform_post.failedA post failed to publish (retries exhausted)
platform_post.failed_waiting_for_retryA publish attempt failed; will retry
platform_post.insightsNew analytics snapshot
comment.createdA comment was synced on an Instagram post
message.received / .sentInbound / outbound DM
message.delivered / .readDelivery and read receipts
message.deletedA message was unsent (Instagram is the only network that reports this)
message.editedAn inbound message was edited
reaction.receivedA reaction was added or removed on a message
referral.receivedA participant entered a DM thread via an ig.me link
profile.connected / .disconnectedConnection state changed
profile.statsNew profile stats snapshot
media.failedA 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; use MANUAL or SS_PERFORMANCE.