event field, never on text inside data.
GET /v1/webhooks/events returns the same list of event names with a description and a category for each (posts, inbox, or accounts). You subscribe to events by name when you register an endpoint.
Event envelope
Every delivery is a JSON object with anevent name, a data value (an object, except an array on a mention.received event sent when you list mentions), and, for events SocialAPI receives from a platform, a raw_payload:
The body carries no event ID and no sent-at time. The
X-SocialAPI-Delivery header identifies the delivery, and X-SocialAPI-Timestamp holds the time of the attempt.
SocialAPI delivers each event at least once, and events can arrive in a different order than they happened. Deduplicate and order on your side.
Route events by brand
Webhook events carrybrand_id, the brand of the connected account, next to account_id. One endpoint receives the events of all your brands, so when you serve more than one customer from one SocialAPI account, route each event to its customer with brand_id.
A post can target accounts of different brands, so
post.scheduled, post.published, post.partial, and post.failed carry one brand_id per target. post.updated, post.deleted, and post.retried name no account and carry no brand_id. To route post.updated and post.retried, read targets[].account_id from GET /v1/posts/{pid}, then each account’s brand_id from GET /v1/accounts. post.deleted fires after the post is deleted, so read targets[].account_id from GET /v1/posts/{pid} before you delete the post, or record each post’s brands when you create it.
Treat brand_id as optional: an event can arrive without it. For example, these cases always arrive without it:
post.unpublishedwithaccount_idset tonull. Route it likepost.updated, withGET /v1/posts/{pid}.comment.receivedandmention.receivedfrom Threads, when the same Threads account is connected to more than one of your brands. Theiraccount_idis the Threads user ID, which is theplatform_user_idof each of those accounts in itsaccount.connectedevent, so you choose which of those brands handles the event.
Platform coverage
Which platforms emit an event is stated under each event as Emitted for. These groups hold across the page:- Instagram, Facebook, Threads, WhatsApp, Telegram, Zalo, and Google Business Profile send comments, direct messages, mentions, or reviews to SocialAPI as they happen, so those events arrive as webhook events. Each platform’s page has a Capabilities table, and Supported platforms compares them.
- X / Twitter, YouTube, Bluesky, Pinterest, and LinkedIn push nothing to SocialAPI. They emit no comment, DM, or review events, and no mention event from the platform: read those with the inbox endpoints. Listing mentions on X and Bluesky sends
mention.received(see Mentions you list). - TikTok sends new comments to SocialAPI, so it emits
comment.received. It has no DM events or review events. Listing TikTok mentions sendsmention.received(see Mentions you list). TikTok accounts also emit thepost.*events for posts you publish through SocialAPI,account.connectedwhen you connect an account, andaccount.disconnectedwhen SocialAPI flags the account for reconnection. A TikTok creator connection emits no comment or mention events, and also emitsaccount.disconnectedwhen the person removes SocialAPI’s app. - Trustpilot is not available, so it emits no events.
Posts
Post events carry the post’s SocialAPI ID, which is a UUID (see IDs). They report the state changes of posts you create through SocialAPI. Thepost.published, post.partial, and post.failed events fire once when the post settles, including a scheduled post and a post on a platform that finishes publishing later.
Emitted for: every platform you can publish to through SocialAPI, for every event in this section.
post.scheduled
Fires when you create a post with a future scheduled_at and it enters the scheduled state.
post.published, post.partial, and post.failed
post.published fires when the post published on every target. post.partial fires when it published on at least one target and failed on at least one other. post.failed fires when it failed on every target. All 3 share one payload.
post.updated
Fires when you edit a draft, scheduled, or failed post.
post.deleted
Fires when you delete a post.
was_status is the post’s status before deletion. A published or partial post is removed from the platforms on a best-effort basis and stays in SocialAPI while any target is still published (see Delete a post). In that case this event does not fire.
post.unpublished
Fires when POST /v1/posts/{pid}/unpublish removes at least one target of a published post from its platform.
account_id is the account the request limited the removal to, and brand_id is that account’s brand. account_id is null when the request did not name an account, and brand_id is then absent. unpublished_count is the number of targets removed from their platform.
post.retried
Fires when a failed or partial post is retried with POST /v1/posts/{pid}/retry. A post.published, post.partial, or post.failed event follows when the retry settles.
retried_count is the number of failed targets sent again.
Comments
comment.received
Fires when a person comments on a post of a connected account. Facebook sends the event again when the person edits the comment.
Emitted for: Instagram, Facebook, Threads (replies to the account’s posts), and TikTok.
The example is the Instagram comment shown in the envelope. The data object is the shared shape in Interaction payload: nested author and content objects. It is not the flat shape (author_id, text) that GET /v1/inbox/comments/{postId} returns. Per platform:
post_id is set on Instagram and Facebook when the post was published through SocialAPI.
Direct messages
Direct message events share the interaction payload. A DM event carries the SocialAPIconversation_id and, except on Zalo, the platform_id of the message. Join platform_id to the platform_id of a row from GET /v1/inbox/conversations/{id}/messages. Do not join on id: the message endpoint returns its own record ID, which differs from the event’s interaction ID.
dm.received
Fires when a person sends a message to a connected account.
Emitted for: Instagram, Facebook, WhatsApp, Telegram, and Zalo. Zalo delivers text messages only.
On Telegram, Instagram, and Facebook a message that replies to an earlier one carries
reply_to, for example "reply_to": { "platform_id": "20" }, with the replied-to message’s platform_id. reply_to is absent when the message is not a reply.
dm.sent
Fires when a connected account sent a message. The sender is author and the person who received it is recipient.
Emitted for: Instagram, Facebook, and WhatsApp.
On Instagram and Facebook the event fires for every message the platform reports as sent from the account: messages sent through the API, replies typed in the platform’s own app or inbox, and DMs your Automations send. The event carries nothing that separates an Automation’s DM from one you sent. On Facebook, raw_payload carries app_id, the ID of the app that sent the message, which tells API sends from replies typed in the Page inbox.
On WhatsApp there is no message echo. The event fires once per message, when WhatsApp reports it as sent, for messages sent with POST /v1/inbox/conversations/{id}/messages or the send-template endpoint. It also fires for each message sent from the phone on a number that stays on the WhatsApp Business app (see WhatsApp). A redelivered receipt does not raise it again, and neither do the later delivered and read receipts. received_at is WhatsApp’s send time, author.id is the sending phone number ID, and recipient.id is the contact’s WhatsApp ID.
dm.status.sent fires alongside dm.sent for the same message.
dm.referral
Fires when a person opens a conversation from an ad or referral link without sending a message. content.text is empty and metadata.referral is always present. The event has no platform_id.
Emitted for: Instagram and Facebook.
dm.received with the same metadata.referral. The referral object holds only the fields the platform sent: ad_id, ref, source, type, and ads_context_data (ad_title, photo_url, video_url).
dm.postback
Fires when a person taps a quick reply or a postback button in a DM. metadata.payload is the payload you set when you sent the button and metadata.title is the button’s title. When the tap arrives through an ig.me link or an icebreaker, metadata.referral is also set. URL buttons open the link in the person’s browser and raise no event.
Emitted for: Instagram and Facebook. WhatsApp sends a tap as dm.received with metadata.interactive_type and metadata.payload.
dm.postback. Their metadata.payload starts with sa1. and the Automation answers the tap itself, so skip payloads that start with sa1.. Do not start the payloads of your own buttons with sa1.. Buttons are described in Direct messages.
dm.deleted
Fires when the sender unsends a message. platform_id names the removed message, which no longer appears in the conversation. content.text is empty.
Emitted for: Instagram.
dm.status.sent, dm.status.delivered, dm.status.read, and dm.status.failed
These events report the progress of a message you sent. Their data is a short status object, not an interaction: match the message by its IDs. account_id and brand_id name the account that sent it.
On Instagram and Facebook:
On WhatsApp:
Mentions
mention.received
Fires in two cases: the platform tells SocialAPI that a connected account was @mentioned in a comment or in a post caption, or you list mentions with GET /v1/accounts/{id}/mentions (see Mentions you list).
Emitted for: Instagram, Facebook, and Threads when the platform reports a mention, and every platform that lists mentions when you list them. Instagram story mentions are not mention.received: they arrive as dm.received (see above).
content, author, and metadata.permalink missing or empty.
On Threads,
GET /v1/accounts/{id}/mentions returns the same mention with the same id, so the event and the list can be matched. Mentions are described on Mentions.
Mentions you list
EveryGET /v1/accounts/{id}/mentions call that returns at least one item also sends one mention.received event, on every platform that lists mentions. A call that returns no items sends none. SocialAPI sends the event on every such call, including a repeated call that returns the same items.
For this event, data is an array: the items of that response’s data, in the same order, each with the fields of the item in the list plus brand_id. The event has no raw_payload. The event a platform notification triggers has an object in data, so a handler for mention.received must accept both an object and an array.
data[].id.
Reviews
Review events do not follow the interaction payload. Google sends only the name of the changed review, sodata holds identifiers and a review object that SocialAPI reads for you. The review object has the same fields as an item of GET /v1/inbox/reviews/{account_id}, so one parser handles both.
Emitted for both review events: Google Business Profile.
review.received
Fires when a customer posts a new review on a connected location.
When more than 1 SocialAPI account has connected the same Google location, each of them receives the event.
review.updated
Fires when a review changes. Branch on change, because one event covers every kind of change.
review are in the review.received table. Reviews are described on Reviews.
Accounts
account.connected
Fires when an account finishes connecting, including when you reconnect it. Use it to show the connected profile or start work that needs the account.
Emitted for: every platform.
account.disconnected
Fires when a connected account is removed or needs reconnecting. It has 2 forms.
The person revoked access on the platform. The account is deleted from SocialAPI. The payload has no reason and no reconnect_required.
status changes so that calls on it signal that it needs reconnecting (see Connect accounts). The payload has reconnect_required: true and a reason.
Emitted for: the platforms listed in the table.
The event’s
reason can differ from the account’s reconnect_reason. When a token check finds a revoked Instagram, Facebook, or Threads login, the event says access_revoked while reconnect_reason holds the specific cause, such as password_changed. On WhatsApp, reconnect_reason is whatsapp_number_unavailable or whatsapp_number_banned where the event says access_revoked or number_banned. Treat reason as the event’s own value.
account.updated
Fires when something changes on the account. Branch on change.
Emitted for: every platform for permissions_reduced. Google Business Profile for every other change.
permissions_reduced fires when X refused a media upload because the account’s access lacks media.write, or when a reconnect granted less than the account had. It does not fire when you remove a permission with PATCH /v1/accounts/{id}. Reconnect the account to ask for the permissions again.
page.removed
Fires when a Page of a multi-page account is found removed. SocialAPI deactivates the page, and it stops appearing in page listings. Other pages of the account stay active.
Emitted for: Facebook.
Interaction payload
Comments, direct messages, and mentions share onedata shape. Fields marked optional are omitted when empty.
Match on
event, not on type.
Use events with Automations
Every inbound Instagram and Facebook event goes both to the webhook endpoints subscribed to it and to your Automations. An Automation removes nothing from your webhook stream. A comment or DM that an Automation answers still arrives ascomment.received or dm.received, and if your own handler also replies, the person gets both replies. No webhook event reports an Automation run: read an Automation’s Firings instead.
Related
- Webhooks: register endpoints, verify signatures, and handle retries.
- Direct messages: send the messages and buttons that produce
dm.sent,dm.postback, anddm.status.*. - Comments: read and answer the comments behind
comment.received. - Reviews: read and reply to the reviews behind
review.received. - Track post delivery: the post statuses and target errors behind the
post.*events. - Supported platforms: the capability matrix for each platform.