Social inbox
A unified thread view over comments and mentions across networks — triage status and assignee, reply in-thread through the provider, draft replies with AI, score sentiment, and convert an author into a CRM contact.
Social inbox
The social inbox joins two streams — engagements (comments, likes, replies
on your posts) and mentions (posts elsewhere that name you) — into one
triage queue. It reads from the social_engagements and social_mentions
tables and is served under GET /v1/social/inbox, so a community manager works
comments and brand mentions from a single view instead of tab-hopping across
networks.
Live surface
Listing, counts, status/assignee/tag triage, in-thread reply, contact
conversion, AI-drafted replies, and sentiment are all real endpoints under
/v1/social/inbox (api/routes/social_inbox.py).
Two kinds, one queue
Every inbox item is either an engagement or a mention, and the
{kind} path segment disambiguates which table a given public_id lives in.
GET /v1/social/inbox/counts powers the open/resolved/archived/assigned-to-me
badges that also feed the dashboard inbox snapshot.
What you can do with an item
| Action | Endpoint | Effect |
|---|---|---|
| Triage | PATCH /v1/social/inbox/{kind}/{public_id} | Set status, assignee, or tags. |
| Reply | POST /v1/social/inbox/{kind}/{public_id}/reply | Post an in-thread reply through the provider's reply() method. |
| Convert | POST /v1/social/inbox/{kind}/{public_id}/convert | Create a CRM contact from the author (records converted_contact_id). |
| AI draft | POST /v1/social/inbox/{kind}/{public_id}/ai-draft | Anthropic-drafted reply suggestion (BYOK). |
| Sentiment | POST /v1/social/inbox/{kind}/{public_id}/sentiment | Recompute the item's sentiment on demand. |
Replying uses the same SocialProvider contract as posting, so a reply goes out
through the network that owns the thread. Converting an author is the bridge
between social listening and your CRM: a helpful commenter or a warm inbound
mention becomes a contact record without re-keying.
Mentions and replies, network by network
| Network | Mentions reach the inbox | Reply from Pact |
|---|---|---|
| Bluesky | Every 5 minutes — mentions, replies and quotes from notifications (free) | Yes, threaded under the right post (root and parent refs), up to 300 characters |
| X | Every 15 minutes, only with your own X app (X bills each post read to the app) | Yes, up to 280 characters |
| TikTok | No | No — the reply box says so and links to the post instead |
| YouTube | No | No — comment replies aren't supported yet; the reply box says so |
Pact never cuts a reply: the reply box counts against the network's limit and
won't send over it. A network Pact can't reply on is said in place of the reply
box, before anyone types (reply_blocked_reason on each inbox item), and the
API refuses the same reply with the same sentence (422 cannot_reply).
A post that mentions two workspaces lands in both: mentions are deduplicated per workspace, never across them. A poll that fails — X's plan has no reads, a sign-in was revoked — is logged as a failure with the reason; it is never counted as "no new mentions", and the account's last synced time does not move.
Inbound depends on provider ingestion
Engagements and mentions populate the inbox two ways: webhooks
(POST /v1/social/webhooks/{provider}, e.g. LinkedIn LMS) where a network
pushes events, and polling (POST /v1/social/posts/{public_id}/poll) as a
fallback for deployments without webhooks. If a network's app credentials or
webhook subscription aren't configured, its items won't appear — the inbox is
only as complete as the ingestion you've enabled per provider.
Sentiment
Items carry a sentiment score so the queue can be sorted and the listening dashboard can chart mood over time. Sentiment is recomputed on demand via the sentiment endpoint — useful after editing or when a thread's tone shifts.