How to Send Facebook Messenger Messages via API
Send and receive Facebook Messenger messages programmatically — Page chats, PSIDs, the 24-hour window, attachments, reactions, and read receipts via the Postproxy API.
The model: chats and messages
A Chat is a conversation between your Facebook Page and one person; Messages inside it are inbound or outbound. Postproxy holds the Page token and the Meta webhook subscription — no Meta app review, no PSID plumbing on your side.
Sends are asynchronous: 202 Accepted with status: "pending", then "published" with external_id once Meta confirms. Failures land in failed_waiting_for_retry (retried with backoff) or failed, with the platform error passed through in error_details.
Send a message
Find the chat, send into it:
# Chats for the Page, most recent activity firstcurl "https://api.postproxy.dev/api/profiles/PROFILE_ID/chats" \ -H "Authorization: Bearer YOUR_API_KEY"
# Sendcurl -X POST "https://api.postproxy.dev/api/chats/CHAT_ID/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "body": "Your order shipped today — tracking inside the app." }'If the Page hasn’t messaged this person yet but you know their PSID (Page-scoped ID, e.g. from an earlier webhook), create the chat first — the call is idempotent and returns the existing chat if there is one:
curl -X POST "https://api.postproxy.dev/api/profiles/PROFILE_ID/chats" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "participant_external_id": "PSID", "participant_name": "Jane Doe" }'The 24-hour window
Meta permits free-form Messenger sends only within 24 hours of the person’s last inbound message. The chat’s last_inbound_at tells you where you stand before sending. The exception is a private reply to a Page post comment, which opens a chat up to 7 days after the comment — it works on Facebook exactly as on Instagram.
Receive messages with webhooks
Inbound messages arrive as message.received events on your webhook endpoint — payload includes the text, attachments (already mirrored to durable storage), and the chat ID to reply into. Messenger also reports lifecycle: message.sent, message.delivered, and message.read map to external_delivered_at / external_read_at on the message.
A reply bot is the webhook handler plus the send call above — match on event.type === "message.received", generate a response, POST it to event.data.object.chat_id.
Attachments
One attachment per send (a Meta Send API limit), as a URL, multipart upload, or base64 — and a send is either text or media, never both:
curl -X POST "https://api.postproxy.dev/api/chats/CHAT_ID/messages" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "media": ["https://yourcdn.com/receipt-4821.pdf"] }'Files are copied to durable storage before dispatch, so the stored url never expires.
Reactions
React to a customer’s message from the Page:
curl -X POST "https://api.postproxy.dev/api/messages/MESSAGE_ID/react" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reaction": "like" }'Messenger expects a unicode emoji; named reactions (love, like, dislike, smile, wow, sad, angry) are translated for you, or pass emoji directly to override. A second react replaces the first — Meta doesn’t stack them. Remove with DELETE /api/messages/MESSAGE_ID/unreact.
Routing signals
Chat metadata carries participant info from Meta: is_verified_user, is_user_follow_business, is_subscribed_to_messenger, is_payment_enabled, plus the owning page_id. Enough to prioritize an inbox without extra Graph API calls.
Messenger vs the other DM platforms
| Capability | Telegram | Bluesky | ||
|---|---|---|---|---|
| Text | Yes | Yes | Yes | Yes |
| Attachments | Yes | Yes | Yes | No |
| Reactions | Yes | Yes | No | No |
| Delivery / read receipts | Yes | Yes | No | No |
| Inbound delivery | Webhook | Webhook | Webhook | Poller (~5 min) |
Same endpoints across all four — which is what makes a unified inbox a rendering exercise instead of four integrations. Full reference: Direct Messages API.