Skip to main content

Troubleshooting: inbound WhatsApp or RCS message never arrives

A contact sends your WhatsApp Business number or RCS agent a message and nothing happens on your side: no conversation in the Inbox, no message.received webhook delivery, and no row you can look up. This page extends Troubleshooting: inbound SMS to your number never arrives to the app-based channels — the failure modes here are different from a missing number routing map, so the fix path is different too. If an inbound SMS to one of your numbers is missing, work the SMS inbound page — a number-routing-map gap is not a cause for WhatsApp or RCS inbound misses, and the checks there do not transfer.

First: confirm the channel is inbound-capable

Inbound app-based channels gate on the channel account itself, not on a number’s capability list:
  • WhatsApp — the WhatsApp Business Account (WABA) must be fully onboarded and its connection row active. In the dashboard, open Settings → Channels → WhatsApp and confirm the WABA shows as Connected with the sender number listed. A half-completed Embedded Sign-up or a bring-your-own (BYO) form missing fields can send outbound while inbound never lands.
  • RCS — the agent must clear all four onboarding gates: brand submitted, agent created, carrier-verified, and launched. Check the agent’s GET /api/v1/rcs/bots/:id/quality — an agent in draft or pending verification carries no inbound traffic at all. The full gate list is on Troubleshoot RCS.
If the channel is not inbound-ready, no diagnostic below will move — fix the gate before anything else.

Where a healthy inbound event surfaces

Every inbound WhatsApp or RCS message passes the same gate sequence. A miss at any one of them looks identical from the outside, so name which stage you lost:
  1. Inbox conversation row — the message opens or appends to a conversation thread (with the channel badge whatsapp or rcs).
  2. message.received webhook — if you subscribed to it. The payload’s channel field is whatsapp or rcs; see the webhook events reference for the full payload shape.
  3. Engagement profiler — the reply scores the contact in real time, and a segment transition on that rescore additionally fires contact.segment_changed for any webhook endpoint subscribed to it.
If you see the message in the Inbox but your endpoint got nothing, the problem is subscription scope, not inbound routing — jump to check 3 below. If neither surface shows it, work the whole cause table.

Cause table — channel-specific failure modes

Work rows from the top; each row narrows the cause class and doubles as an escalation input.

WhatsApp-specific causes in detail

Meta webhook subscription missing. Inbound WhatsApp traffic only reaches Orbit when Meta’s webhook subscription was installed on the WABA at connect time. Re-running Embedded Sign-up fixes this in-place — the templates, phone numbers, and quality history survive; only the subscription wiring refreshes. Full re-auth flow: Troubleshoot the WhatsApp connection. Connection token expired mid-inbound. A token that fails Meta’s validation flips the WABA health check to invalid — internal logs tag it WHATSAPP_CONNECTION_INVALID. Inbound drains stop because Meta holds the message back at its side. Re-authenticate via the connection page; the token is dead, not busy. 24-hour window misreading. A message.received event represents an inbound reply, which always re-opens the 24-hour freeform window. If your consumer-side handler gates on WHATSAPP_OUTSIDE_24H_WINDOW on the reply path, it misbooks a valid inbound as unreachable — the 24h window guide spells the state machine out.

RCS-specific causes in detail

Agent not launched or verified. RCS business messaging gates inbound the same way it gates outbound — an agent stuck at draft or pending verification carries no inbound. Confirm at GET /api/v1/rcs/bots/:id/quality; the gate list is on Troubleshoot RCS. Fallback-to-SMS masking the channel. When the sender’s reply arrives under the SMS fallback (RCS capability absent on their handset at reply time), Orbit records it as channel: "sms" on the same conversation thread. RCS-scoped automations and any dashboard filter on channel: rcs will not see it — a misclassification, not a drop. The send-side mirror is documented on Troubleshoot RCS. File-check capability missing. An RCS-rich reply whose file-check capability is absent (an attachment the gateway cannot validate) can be short-circuited before it lands in the Inbox — the inbound equivalent of the rich-card schema rejects described on Troubleshoot RCS.

Diagnostic steps

Work these in order; each narrows to a specific gate.
  1. Read the delivery log for the inbound event. List your webhook endpoints with GET /api/v1/webhooks, then read the endpoint’s recent deliveries with GET /api/v1/webhooks/{endpoint_id}/deliveries — the event you want is message.received with channel: "whatsapp" or channel: "rcs". An empty list means the event never fired (routing miss); a failed delivery row means the endpoint rejected or timed out (subscription or receiver-side issue). Tooling and replay flow: Inspecting deliveries.
  2. Check your webhook subscription scope. GET /api/v1/webhooks returns each registered endpoint with its subscribed events list. message.received must be on it (or the endpoint normalized-inbound envelope normalized.inbound, which covers the inbound family at once — see normalized inbound envelope). A paused or mis-scoped endpoint receives nothing even when routing succeeded.
  3. Verify the endpoint’s event list matches the channel you added. An endpoint registered before a second WABA or RCS agent was attached stays live in the dashboard with its original scoping — adding the channel alone does not extend the endpoint’s event list. If you connected the channel after the endpoint, re-save the endpoint with message.received on its event list so the new channel joins the subscription.
  4. Confirm the exact destination. For WhatsApp, have the sender read back the number they messaged and compare it to the WABA’s display number in Settings → Channels → WhatsApp. A sender who messaged your personal WhatsApp or a second WABA you own means the message never reached this org’s surface at all.

Worked example — a WhatsApp inbound that never fires message.received

A contact replies to your WABA. The Inbox shows the reply. Your automation does nothing. The check sequence:
  • If the delivery list is empty for message.received: routing missed at the Meta-subscription layer — reconnect via the connection page and retry.
  • If the delivery row failed: the endpoint receiver rejected or timed out — check your handler’s signature verification and latency budget, then replay the delivery once the receiver is healthy.
  • If the delivery succeeded but your automation still missed: the payload was consumed by a stale handler version — a channel field reading whatsapp is the branch your automation keys on.

Worked example — an RCS inbound that fell back to SMS

A contact replies to your RCS campaign. The Inbox shows the reply with an sms channel badge, and your RCS-scoped automation never fires.
  1. Confirm the message row on GET /api/v1/messages/:id carries channel: "sms", not rcs.
  2. Check the contact’s handset capability at reply time — GET /api/v1/rcs/capability/:botId/:recipient returns isCapable: false when the handset has no RCS route, which makes the fallback-to-SMS classification correct rather than a routing miss.
  3. Branch your automation on both channel values you accept (or fall through to the default inbound route) — treating the fallback row as “not an RCS reply” is a scope choice, not a platform fault. The send-side capability probe documentation is on Troubleshoot RCS.

Escalation bundle

Open a support ticket when a reply to a healthy WABA or a verified RCS agent never shows up in either surface after the checks above. Include all of these so Support can trace the routing step directly:
  • The message row id if any row exists (even the sms-fallback row), or the exact sender + recipient pair and timestamp if no row exists at all.
  • The WABA id (for WhatsApp) or the RCS agent id / bot id (for RCS).
  • The time window of the missed inbound event (with timezone).
  • The webhook endpoint id if you were expecting a message.received delivery — supports narrowing to either a routing miss or a delivery failure without a back-and-forth.

See also