Skip to main content
The unified inbox is SocialAPI’s REST API for reading and answering what people send to your connected accounts: comments, direct messages (DMs), reviews, and mentions. Each area has its own endpoints. All of them use the same API key, the same IDs, the same cursor pagination, and the same 501 resource.not_supported answer when a platform lacks a feature. Replies and DMs cost interaction credits, and reads cost nothing. Which platforms support which action is in the capability matrix. An account needs the matching permission for each area: comments.read and comments.write, messages.read and messages.write, or reviews.read and reviews.write. A call without it returns 403 account.permission_missing (the lists of stored comments, conversations, and messages and GET /v1/inbox/reviews are the exceptions: see Account permissions), and the account’s events for that area do not arrive.

The four areas

Answer Instagram and Facebook comments and DMs that match keywords without running a webhook handler by using an Automation.

The interaction shape

An Interaction is the one object that webhook events and GET /v1/accounts/{id}/mentions use for a comment, DM, or mention. This is one item of that mentions list:
id starts with sapi_cmt_, sapi_dm_, or sapi_mnt_ by type. Every field is in Interaction payload. The list endpoints of the other areas return their own item shapes, described in each guide: comments with a capabilities object, conversations and messages, and reviews with a reply. IDs have one format everywhere: see IDs.

Receive new items

SocialAPI sends new inbound items to your server as webhook events when the platform reports them to SocialAPI. Which platform emits which event is stated per event on Webhook events. X, YouTube, Bluesky, Pinterest, and LinkedIn send nothing to SocialAPI. Where they support comments, DMs, or mentions, read them with the list endpoints. Register an endpoint once to receive the events of the other platforms.

Costs

Interaction credits count the replies and DMs you send. A plan with an interaction allowance returns 429 validation.interaction_limit_exhausted when it is used up.
  • 1 credit: a public reply to a comment, a reply to a review, a reply to a mention, and one DM request, however many messages it sends.
  • No credit: every read, private replies, hiding, liking, and deleting a comment, message reactions, and a manual sync.
Plans and usage is the home of these rules.

Fetch an inbound attachment

GET /v1/inbox/media/{id} returns the bytes of an attachment that arrived with a WhatsApp or Telegram message. On every other platform, the attachment URL on a message is the platform’s own URL: you fetch it directly, and it expires when the platform says. WhatsApp and Telegram files can be downloaded only with the connected account’s own credentials, which your API key cannot present. For those two platforms, attachment_url on the message and content.media[].url on the dm.received event are a SocialAPI URL of the form https://api.social-api.ai/v1/inbox/media/{id}. SocialAPI starts fetching the file when the message arrives. It stays available for 30 days, then returns 410.
A request for a file that is still being fetched waits up to 15 seconds for it before it returns 504. 410 and 504 mean opposite things: 410 means stop, 504 means keep retrying. A file that cannot be downloaded at all, such as a Telegram file over 20 MB, returns 410.

Refresh the inbox manually

Use POST /v1/inbox/sync to refresh conversations and messages on demand, for example to load a thread before you open it. With only account_id, the sync refreshes that account’s conversation list, then loads the messages of up to 20 of its most recent conversations that were never loaded. Add conversation_id to refresh that one thread’s messages instead.
Response (HTTP 202):
To wait for the result, poll GET /v1/inbox/sync with the same account_id and conversation_id until state is no longer syncing, then read the conversation or message list again:
A POST for a target that is already syncing returns that running job and starts no second one. Each target accepts 1 sync you start every 5 minutes. A second attempt inside that time returns 429 inbox.sync_rate_limited with a Retry-After header holding the seconds to wait, and error.meta.retry_after_seconds repeats it. Reads of the inbox never use this allowance. GET /v1/inbox/conversations and GET /v1/inbox/conversations/{id}/messages also return sync_state and last_synced_at, so a client that already polls them does not need GET /v1/inbox/sync. An unknown account_id or conversation_id returns 404, and a missing account_id returns 400 validation.field_required.

Scopes

A scoped key needs the scope that each guide lists for an operation: inbox:read, inbox:write, dms:read, or dms:send. Starting or reading a sync needs dms:read. Scoped API keys lists what each scope grants.
Last modified on October 19, 2026