Skip to main content
The Instagram API in SocialAPI connects an Instagram Business or Creator account through Instagram Login by default, or through Facebook Login when the account has a linked Facebook Page: see Connect through Facebook Login. It publishes posts, Reels, carousels, and Stories, reads and moderates comments, sends private replies and direct messages (DMs), and reads mentions, stories, and insights. SocialAPI’s own Meta app connects the account, so you register nothing: see Platform apps.

At a glance

Capabilities

An unsupported call returns 501 resource.not_supported. Read the capabilities object on each comment instead of assuming (can_like, can_private_reply). The cross-platform matrix is on Platforms.

Connect an account

Connect with POST /v1/accounts/connect and "platform": "instagram". The shared flow, request fields, and result are in Connect accounts, and the redirect parameters are in Redirect parameters.
Response (HTTP 202):
Instagram-specific rules:
  • Account type. The person must connect an Instagram Business or Creator account. A personal account cannot be connected.
  • One account per brand. A brand holds one Instagram account. With Facebook Login, each further Instagram account the login granted appears as a Page of the brand’s Instagram account. Connecting a different Instagram account to the same brand ends with status=error and error=account.already_linked on your redirect_uri.
  • Reconnect. If a token is no longer valid, calls return 401 platform.instagram.auth and the account needs reconnecting. See Reconnect an account.
  • Permissions. Send permissions to ask the person for fewer scopes: see Scopes.

Connect through Facebook Login

Connect through Facebook Login when the Instagram account has a linked Facebook Page and you need to delete published posts, like comments, or set the paid-partnership label. Instagram Login stays the default: send no connection_type and nothing changes. The two paths are the same platform, instagram, and every call, field, and webhook event is the same unless this section says otherwise. Select Facebook Login with metadata.connection_type: "facebook_login" on POST /v1/accounts/connect. Any other value, or none, connects through Instagram Login.
Response (HTTP 202):
The person signs in to Facebook, not Instagram, and approves the scopes in Facebook Login scopes. The redirect then carries status=success and the brand’s Instagram account, as described in Redirect parameters.

More than one Instagram account under one login

A Facebook login can administer more than one Instagram account. The brand’s Instagram account holds every Instagram account the login granted that none of your other brands holds, each as a Page. The platform_page_id of such a Page is the Instagram account ID. List the Pages with GET /v1/accounts/{id}/pages, and publish to one with page_id on the post target: see Delivery. A Facebook Page with no linked Instagram account is not listed.
  • A login that grants no Instagram account ends with status=error and error=platform.instagram.no_pages on your redirect_uri.
  • A login whose every Instagram account belongs to another of your brands, or is already held through Instagram Login, ends with status=error and error=platform.instagram.no_assignable_pages.
  • A brand whose Instagram account is connected through a different Facebook login ends with status=error and error=account.different_login. Disconnect the brand’s Instagram account first.

Requirements

  • The Instagram account is a Business or Creator account linked to a Facebook Page. An account with no linked Page does not appear in the connection: use Instagram Login.
  • The person holds the Page task that each capability needs. Meta grants an Instagram scope only for a task the person holds on the Page: create content for publishing, moderate for comments, messaging for DMs, and analyze for insights.
  • A DM or private reply on an account with no Facebook Page linked to it returns 409 platform.instagram.no_page. Reconnect the account.

One path per Instagram account

Hold each Instagram account through one path. Connecting through Facebook Login does not add an account that you hold through Instagram Login: if no account remains, the connection ends with status=error and error=platform.instagram.no_assignable_pages. To switch an account to Facebook Login, disconnect it, then connect it again with connection_type: "facebook_login".

Differences from Instagram Login

Every other row of the Capabilities table behaves the same on both paths.

Facebook Login scopes

SocialAPI’s Meta app requests these scopes at connect. You apply for no app review. Each scope belongs to the account permissions in the last column, and the consent screen asks for the scopes of the permissions you selected. The scopes marked Every account are always requested. The account stays limited to the permissions you selected: an account connected with comments.read alone cannot reply to comments.

Comments

List comments on a post with GET /v1/inbox/comments/{postId}, where postId is the post’s platform ID (targets[].platform_post_id). Reply, hide, unhide, and delete work as described in Comments. Instagram-specific rules:
  • On Instagram Login, a comment’s capabilities.can_like is always false, because Instagram has no like endpoint for comments on that path. On Facebook Login it is true.

Private replies

A private reply sends a DM to the person who commented. Send it with POST /v1/inbox/comments/{postId}/{commentId}/private-reply.
  • Instagram allows one private reply per comment, within 7 days of the comment. A second reply, or a comment older than 7 days, returns 400 platform.instagram.private_reply_ineligible.
  • A private reply does not open the 24-hour messaging window: the person’s answer does.
  • The request accepts up to 3 buttons, sent as a button template.
  • An Automation can send the private reply whenever a comment matches its keywords.

Direct messages and the messaging window

An Instagram account can message a person only inside the 24-hour messaging window that the person’s last message opened. Outside it, the send returns 400 platform.instagram.window_closed. On Instagram Login, send message_tag: "HUMAN_AGENT" to reply up to 7 days after the person’s last message. Instagram Login accepts no other tag: any other value returns 400 validation.invalid_message_tag. On Facebook Login, message_tag is not sent: the DM goes out untagged and the 24-hour window applies.
  • Message types. Text, attachments, quick replies, buttons, and cards. Each attachment in attachments[] has a source_type (url, media_id, or platform_attachment_id) and a type. type is required for platform_attachment_id, or the request returns 400 validation.attachment_type_required. Field rules are in Direct messages.
  • Size limits. Instagram sets them and refuses a larger message: text up to 1,000 bytes of UTF-8; images in PNG or JPEG up to 8 MB; video in MP4, OGG, AVI, MOV, or WebM up to 25 MB; audio in AAC, M4A, WAV, or MP4 up to 25 MB; files in PDF up to 25 MB.
  • Unsending. Instagram does not let apps unsend or delete a sent DM. When the other person unsends a message, you receive a dm.deleted event and the message disappears from the conversation.
  • Reactions. POST /v1/inbox/conversations/{id}/messages/{messageId}/reaction reacts to a message with any emoji, and DELETE on the same path removes the reaction.
  • Story mentions. A story that mentions your account arrives as dm.received with an attachment of type story_mention, not as mention.received.

Participant profile

GET /v1/platforms/instagram/accounts/{id}/participants/{participantId}/profile returns the profile of a person in a conversation, including whether they follow the account (is_user_follow_business) and whether the account follows them (is_business_follow_user). participantId is the participant_id of the conversation.
Response (HTTP 200):
  • Read the follow fields at each call, because they change when a person unfollows.
  • profile_pic links expire: do not store them.
  • Instagram discloses a profile only for a person who messaged the account or tapped an icebreaker or the persistent menu. For anyone else the call returns 403 platform.instagram.230, which means Instagram withholds the data. It does not mean the person does not follow the account.
  • A field that Instagram has no value for, such as name, is absent.
  • is_verified_user, is_user_follow_business, and is_business_follow_user are absent when false, and follower_count is absent when it is 0. An absent follow flag means the person does not follow in that direction, or Instagram did not report it: the response does not tell the two apart. When Instagram withholds the relationship because the person has not given consent, the call returns 403 platform.instagram.230 instead.

Mentions

GET /v1/accounts/{id}/mentions returns media in which another account tagged yours. An @mention written in a caption or a comment is not in that list: it arrives as a mention.received event, with metadata.mention_type set to comment or caption. Reply to a mention with POST /v1/accounts/{id}/mentions/reply. A story mention arrives as a DM: see Direct messages. Details are in Mentions.

Stories

GET /v1/platforms/instagram/accounts/{id}/stories lists the stories that are live now. Instagram removes a story 24 hours after posting, so a call returns nothing older. The request takes limit (1 to 100, default 20) and cursor, and no since.
Response (HTTP 200):
Each item has id, platform, caption, media_type, media_url, permalink, timestamp, like_count, comments_count, shares_count, view_count, account_id, and metadata. like_count, comments_count, shares_count, and view_count are always 0 on a story. An item also carries settings when Instagram reports any: see Settings on published posts. metadata.is_story is always true, and metadata.expires_at is the posting time plus 24 hours. For a video story with no media_url, the cover image is returned as media_url.

Collaboration invites

A collaborator is invited when a post is published, with platform_data.collaborators: see Instagram publishing. Instagram has no call that adds a collaborator to a published post. Three calls remain: The list call returns HTTP 200:
status is accepted, pending, or declined. Accepting or declining with no pending invite for the account on that media returns an error from Instagram. Accept and decline return {"success": true}.

Account summary

GET /v1/platforms/instagram/accounts/{id}/summary returns live profile counts and insight totals for the trailing 30 days.
Response (HTTP 200):
The insight totals need the analytics.read permission on the account. An account without it returns 403 account.permission_missing. When Instagram withdraws the insights access, the next call can return 403 platform.instagram.insights_scope_missing instead: reconnect the account. Instagram’s insight data can lag by up to 48 hours. Per-post and per-account metrics over a window you choose are in Analytics.

Webhook events

Instagram accounts emit these events to your webhook endpoints. Payloads are in Webhook events. Every post.* event in Webhook events is emitted for this platform.

Limits

GET /v1/accounts/{id}/limits returns posts_remaining, the posts left in Instagram’s rolling 24 hours.

Scopes

SocialAPI’s Meta app requests these scopes at connect through Instagram Login. You apply for no app review. The scopes of Facebook Login are in Facebook Login scopes. Each scope belongs to the account permissions in the last column, and the consent screen asks for the scopes of the permissions you selected. instagram_business_basic is always requested. Instagram asks for comments and for messages as 1 scope each, covering both reading and writing, so the consent screen shows the broader scope. The account stays limited to the permissions you selected: an account connected with comments.read alone cannot reply to comments.
Last modified on October 19, 2026