Skip to main content

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_messaging scope approval — the OAuth dialog asks for pages_messaging and pages_show_list. If your company policy routes Meta app review through a central team, pre-approve those two scopes or the connect step stalls.
You do not need a Meta developer app, a WABA, or any contracted Meta seats to do any of this. Messenger is $0 on Orbit’s side — see Pricing.

2. Connect a Page (OAuth → selection → webhook subscription)

Do this once per Page. If you manage a brand portfolio, repeat for each Page.
  1. In the dashboard, go to Channels → Messenger.
  2. Click Connect Page. Meta’s OAuth dialog opens and requests pages_messaging and pages_show_list.
  3. 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.
  4. Orbit subscribes the Page to webhook events automatically — you do not wire callbacks by hand.
  5. (Recommended) Send yourself a test message to the Page from a personal Facebook account, then confirm the inbound message.received event 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:
A 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 the ref parameter.
  • 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.
Do not treat PSIDs as globally portable — a recipient that messages Page A then Page B shows a different PSID for each. Key your contacts by (PSID, Page) unless you have resolved identity across them in CDP.

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.
Skip personas if you only send template/automation traffic; they exist for conversational inbox use.

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. A MESSAGE_TAG send without a valid tag field is rejected.
  • OTN — see One-Time Notifications.
Rule of thumb: if you can work inside 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.
  1. 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.
  2. 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.
Design notes:
  • 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_TAG or HUMAN_AGENT.

7. What fires a webhook — and what does not

Design your automation against the actual event surface.
  • Inboundmessage.received fires for inbound text and attachment messages (the ones users send in the thread).
  • Outbound lifecyclemessage.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.received for them; rely on the routing Orbit does internally.
  • Delivery signal — treat message.delivered as confirmation; message.sent only means acceptance by Meta.
When you design flows that must react to a button tap or an ad referral, do the reaction inside Orbit (flow/inbox automation), not in your webhook consumer.

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_RECIPIENT on 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:
  1. Wait for the user to re-engage (cheapest — the window re-opens).
  2. Switch to messaging_type: MESSAGE_TAG with an approved transactional tag.
  3. Switch to messaging_type: HUMAN_AGENT if a human is genuinely replying.
  4. Consume an OTN token if you hold one.
Do not blindly retry the same call — the window is still closed.

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