501 resource.not_supported.
A DM request costs 1 interaction credit, however many messages it sends. Reads and reactions cost nothing. Each platform decides when you can message a person: see The messaging window.
Endpoints
{id} is the conversation id that GET /v1/inbox/conversations returns. It is a UUID, not a sapi_dm_ ID. {messageId} is a message’s platform_id. See IDs.
Your first message
List the conversations of one connected account:message_ids lists the SocialAPI ID (sapi_dm_) of every message the request sent, in send order. message_id is the first one and is deprecated. On Zalo, message_id is empty and each entry of message_ids is an empty string. To get the platform ID of a sent message, read it from the message list (platform_id). A conversation that belongs to another connected account than account_id returns 404 conversation.not_found.
Conversations
GET /v1/inbox/conversations lists conversations, most recent activity first.
PATCH /v1/inbox/conversations/{id} with { "status": "archived" } or { "status": "active" } changes the status and returns { "success": true }. Any other value returns 400 validation.field_invalid. POST /v1/inbox/conversations/{id}/read sets unread_count to 0 and returns { "success": true }. It does not send a read receipt to the person.
Read messages
GET /v1/inbox/conversations/{id}/messages lists the messages of a conversation, newest first.
limit is 25 by default. A value above 200 is treated as 200, and a value of 0 or less, or one that is not an integer, is treated as 25. See Pagination.
Send a message
POST /v1/inbox/conversations/{id}/messages sends a message into a conversation. A request must hold text, an attachment, or interactive content, and can hold all three. A request with none returns 400 validation.field_required.
SocialAPI sends text first, then each attachment in order, as separate messages. Text plus 2 images arrives as 3 messages, and the request still costs 1 credit.
Attachments
Each item ofattachments names a media source:
url attachment from your URL, so it must be reachable without a login. Facebook accepts files up to 25 MB. Instagram accepts images up to 8 MB and video, audio, and PDF files up to 25 MB. SocialAPI resolves every media_id before it sends anything, so an unknown or unfinished media_id returns 400 validation.media_unresolved and sends no message. If a send fails part way, the earlier messages stay delivered. The error carries error.meta.sent_count (messages sent) and error.meta.failed_index (the item that failed, counting text as item 0 when present), so you can retry from there.
Some platforms accept less. X sends text only and rejects an attachment with 400 validation.attachment_unsupported. Bluesky sends only text. Zalo sends a url or media_id attachment as an image unless its type is gif or sticker. Telegram accepts attachments with captions. See X, Bluesky, Zalo, and Telegram.
Interactive messages
Instagram sends structured, tappable content. A Facebook DM send delivers onlytext and ignores quick_replies, buttons, and cards, so the rules in this section apply to Instagram. Buttons do work on a Facebook private reply. Set at most 1 of quick_replies, buttons, or cards per message. More than 1 returns 400 validation.interactive_conflict. When the person taps a quick reply or a postback button, SocialAPI sends a dm.postback event with the payload you set. To answer taps without your own handler, use an Automation. Interactive content follows the messaging window like any message.
Quick replies
Quick replies are up to 13 tappable chips above the keyboard. They needtext.
More than 13 returns
400 validation.too_many_quick_replies. A title over 20 characters returns 400 validation.quick_reply_title_too_long.
Buttons
Buttons are a text bubble with 1 to 3 buttons.text is the body and holds 640 characters at most (400 validation.text_too_long).
More than 3 buttons returns
400 validation.invalid_button_count.
Cards
Cards are a carousel of up to 10 cards, each with an image, a title, a subtitle, and up to 3 buttons.
More than 10 cards returns
400 validation.too_many_cards. More than 3 buttons on a card returns 400 validation.too_many_buttons. A title or subtitle over 80 characters returns 400 validation.card_text_too_long.
React to a message
POST /v1/inbox/conversations/{id}/messages/{messageId}/reaction adds your emoji reaction to a message, and replaces your earlier one. It works on Instagram and Facebook. Other platforms return 501 resource.not_supported.
reaction is the emoji character itself, a single emoji. Anything else returns 400 validation.invalid_reaction. DELETE on the same path, with account_id as a query parameter, removes the reaction. A reaction costs no credit.
The messaging window
Most platforms let you message a person only for a limited time after their last message. A send outside the window fails, and SocialAPI sends nothing.- Instagram and Facebook: 24 hours from the person’s last message. Outside it, the send returns
400 platform.instagram.window_closedor400 platform.facebook.window_closed. On Instagram Login,message_tag: "HUMAN_AGENT"extends the window to 7 days. Instagram Login accepts no other tag: any other value returns400 validation.invalid_message_tag. A Facebook Page, and an Instagram account connected through Facebook Login, send nomessage_tag: the DM goes out untagged. - WhatsApp: a free-form message needs the 24-hour service window, and outside it the send returns
400 whatsapp.window_closed. An approved template is the way to reach the person: see WhatsApp. - Zalo: the person must have interacted with the Official Account in the last 7 days. Outside it, the send returns
422 platform.zalo.not_deliverable: see Zalo. - Telegram: the person must have messaged the bot first. Before that, the send returns
403 telegram.cannot_message: see Telegram.
message_tag is not refused this way. A send on Instagram connected through Facebook Login goes out untagged, so it is refused. A private reply does not clear the refusal. The person’s next message does.
Limits
Each DM request costs 1 interaction credit. When the allowance is used up, the call returns
429 validation.interaction_limit_exhausted. Plans and usage lists what costs a credit.
Platform support
Which platform supports DMs, attachments, interactive content, and reactions is in the capability matrix. Each platform page lists its own rules: Instagram, Facebook, X, WhatsApp, Telegram, Zalo, and Bluesky. Threads, YouTube, Pinterest, and Google Business Profile have no DMs.Errors and debugging
Check these in order when a send fails:401,403 auth.insufficient_scope. The key is invalid, or a scoped key lacksdms:send.404 conversation.not_found,404 account.not_found,403 account.reconnection_required. The conversation is not yours or belongs to another connected account thanaccount_id, or the account needs reconnecting.403 account.permission_missing. The account lacks the permission the call needs:messages.writeto send a message or a reaction, andmessages.readto start or read an inbox sync.error.meta.permissionnames it. The conversation and message lists return what SocialAPI stored and never return this error: an account withoutmessages.readstores no new messages.400 validation.*. The body is wrong.error.meta.fieldnames the field. The codes are in Send a message and Interactive messages.400 platform.instagram.window_closed,400 platform.facebook.window_closed,400 whatsapp.window_closed,422 platform.zalo.not_deliverable,403 telegram.cannot_message. The messaging window is closed: see The messaging window.422 platform.instagram.thread_unavailable,422 platform.facebook.thread_unavailable. The platform refused to deliver to this conversation, which can be restricted or unavailable.403 platform.instagram.permission_denied,403 platform.facebook.permission_denied. The platform scopes granted at connect do not cover the action. Reconnect the account and approve every scope.429 validation.interaction_limit_exhausted,429 platform.{platform}.rate_limit. Your allowance, or the platform’s own limit. ReadRetry-After: see Rate limits.501 resource.not_supported. The platform has no DMs, or no reactions.
POST /v1/inbox/sync. The full catalog is in Errors.
Scopes
Events
SocialAPI sends DM events to your webhook endpoint:dm.received, dm.sent, dm.postback, dm.referral, dm.deleted, and dm.status.*. Each is described, with the platforms that emit it, on Webhook events. An account without the messages.read permission receives none of the dm.* events, except that, with messages.write alone, the account still receives dm.status.read on Instagram, dm.status.delivered and dm.status.read on Facebook, and every dm.status.* event on WhatsApp. It receives no dm.sent and no dm.status.sent on Instagram or Facebook.
Use from an AI agent
There is no tool for reactions or for inbox sync. See MCP tools.
Related
- Comments: private replies start a DM conversation from a comment.
- Automations: send DMs and answer button taps without your own handler.
- Webhook events: the DM event payloads.
- Rate limits: platform limits on sending.
- Platform support: which platform supports which DM feature.
- Account permissions: the permissions an account needs to read and send messages.
- Unified inbox: inbound attachments and manual sync.