Messenger Onboarding Playbook
This guide walks you end to end from an empty Messenger channel to a working, monitored setup. It complements the Messenger channel page, which documents the API shapes — this guide is the ordered playbook you follow the first time (and re-run when you attach an nth Page). The whole path takes minutes: unlike WhatsApp or 10DLC, there is no approval cycle, no registration, and no Orbit-side cost.1. Prerequisites
Before you open the dashboard, confirm:- A Meta Business Manager account at business.facebook.com that you (or your org admin) can access.
- Ownership of the Facebook Page you want to attach — you must be a Page admin; Meta’s OAuth dialog only lists Pages your Facebook user controls.
pages_messagingscope approval — the OAuth dialog asks forpages_messagingandpages_show_list. If your company policy routes Meta app review through a central team, pre-approve those two scopes or the connect step stalls.
2. Connect a Page (OAuth → selection → webhook subscription)
Do this once per Page. If you manage a brand portfolio, repeat for each Page.- In the dashboard, go to Channels → Messenger.
- Click Connect Page. Meta’s OAuth dialog opens and requests
pages_messagingandpages_show_list. - Select the Page(s) to attach. Pick them all now if you intend to run several; each selected Page becomes a distinct channel entry on Orbit.
- Orbit subscribes the Page to webhook events automatically — you do not wire callbacks by hand.
- (Recommended) Send yourself a test message to the Page from a personal Facebook account, then confirm the inbound
message.receivedevent appears on your webhook endpoint before you go live.
API equivalent
OAuth is dashboard-only — there is no API endpoint to complete the Meta sign-in — but the send call after Page attach is the same shape every time:queued status in the response means Meta accepted the send request; treat message.delivered as your real delivery signal (see What fires a webhook).
3. Recipient PSIDs — where the recipient ID comes from
Every Messenger send addresses a recipient by PSID (Page-Scoped ID), not a Facebook user id or an email. A PSID is stable per (recipient, Page) pair but differs across Pages. You receive the PSID:- Inbound webhooks. Every inbound message carries the sender’s PSID; store it on the contact so outbound replies reuse it. This is the primary path for conversational use cases.
- m.me links. A link of the form
m.me/<page-id>opens your Page’s Messenger thread; when the user messages, the PSID arrives on the inbound webhook — link PSIDs back to the referring campaign by parsing therefparameter. - Referral events from ads or plugins. When a user comes in through a Click-to-Messenger ad or a web plugin, Meta delivers a referral alongside the message; Orbit surfaces the PSID on the inbound event the same way.
4. Personas — reply as a named agent on the same Page
If your agents reply individually (e.g. “Sarah, Support”) instead of the brand silhouette, configure sender personas from Settings → Channels → Messenger after Page attach. Each persona has a name and optional avatar; agents pick a persona when composing from the inbox, and outbound messages carry that persona label to the recipient. Limits that matter operationally:- Personas are per Page — building them per Page is part of onboarding a Page.
- Personas apply to PSID-typed recipients only; they do not change behaviour on SMS/WhatsApp/email.
- The Page itself still owns identity and routing — a persona is a display label, not a separate sender.
5. Messaging windows and tags — choose the right messaging_type
The channel page table lists the four shapes. In practice:
RESPONSE(standard 24h window) — the default; any content, inside 24h since the user’s last message. Most conversational traffic.HUMAN_AGENT— up to 7 days; use only for human support agents catching up to a backlog, not for scheduled/template sends.MESSAGE_TAG— anytime, but only with one of Meta’s approved tags (CONFIRMED_EVENT_UPDATE,POST_PURCHASE_UPDATE,ACCOUNT_UPDATE) and only transactional content. AMESSAGE_TAGsend without a validtagfield is rejected.- OTN — see One-Time Notifications.
RESPONSE, do; escalate to HUMAN_AGENT for real agent replies; use MESSAGE_TAG for transactional receipts/updates; use OTN for the single re-engagement follow-up. Meta enforces these and will 422 on misuse.
6. One-Time Notification (OTN) tokens
OTN is the escape hatch when none of the windows fit and you need one more message — a re-engagement prompt, a cart-recovery ping, notification opt-in. The trade is deliberate: one token buys exactly one message.- Request the token. Send an OTN request message to the user (inside an open window) that asks them to opt in to a one-time follow-up. Meta renders the prompt; the user’s tap stores a token against their PSID.
- Spend the token later. A subsequent send that references the token can go through even after the 24h window has closed — once. After that the token is consumed.
- Request tokens as soon as the user engages if re-engagement is part of the lifecycle (e.g. cart abandonment in commerce flows) — you cannot request after the window closes.
- The token is per-PSID and single-use; track spend server-side.
- OTN is for a single follow-up, not a campaign batch. For real batch follow-up outside the window, the channel is still governed by
MESSAGE_TAGorHUMAN_AGENT.
7. What fires a webhook — and what does not
Design your automation against the actual event surface.- Inbound —
message.receivedfires for inbound text and attachment messages (the ones users send in the thread). - Outbound lifecycle —
message.sent(Meta accepted),message.delivered(reached the device),message.read(recipient opened the conversation),message.failed(Meta-reported delivery failure). - Not dispatched — postbacks (button taps), referrals (m.me links, Click-to-Messenger ads), and Opt-in plugin events are processed by Orbit but do not fire webhooks. Do not build automations that expect a
message.receivedfor them; rely on the routing Orbit does internally. - Delivery signal — treat
message.deliveredas confirmation;message.sentonly means acceptance by Meta.
8. Common errors — deep dive
The channel page table is the reference. Here is how to fix each in practice.INVALID_RECIPIENT (422)
The recipient PSID is missing or empty in to. Fixes:
- Confirm you captured the PSID from an inbound webhook (or a m.me link flow) before you try to send; a
INVALID_RECIPIENTon first send almost always means the capture step was skipped. - Validate the PSID string in your integration before calling the API — empty/whitespace strings reach Meta otherwise.
MESSAGING_WINDOW_CLOSED (422)
You sent a RESPONSE/UPDATE message (or a MESSAGE_TAG without a tag) more than 24h after the recipient’s last inbound. The response details includes hours_since_last_inbound and last_inbound_at — log both before choosing a recovery path.
Recovery, in escalating cost:
- Wait for the user to re-engage (cheapest — the window re-opens).
- Switch to
messaging_type: MESSAGE_TAGwith an approved transactional tag. - Switch to
messaging_type: HUMAN_AGENTif a human is genuinely replying. - Consume an OTN token if you hold one.
MESSAGE_SEND_FAILED (502)
Meta’s Send API rejected the request. Upstream detail is in details.provider_message; check it before opening a support ticket.
- Expired Page access token — Meta rotates tokens roughly every 60 days. Reconnect from Channels → Messenger → Reconnect.
- Dropped webhook subscription — re-subscribe from the channel detail page (Re-subscribe).
- Invalid/blocked recipient — Meta sometimes blocks delivery to a PSID after spam reports or Platform terms actions; treat as a genuine failure and suppress future sends to that PSID.
RATE_LIMIT_EXCEEDED (429)
Per-tenant send rate exceeded. Honour Retry-After and, for campaigns, batch through the campaign channel rather than a single-message loop. For sustained throughput, see Requesting Higher Limits.
Where to go next
- Messenger channel page — the API reference for channel-specific body shapes.
- Send and receive messages — the cross-channel send pattern.
- Inbox setup — route inbound Messenger traffic to your team.
- Best practices — platform-wide sending hygiene.