Skip to main content

Messaging windows and off-window sends

For two channels — Meta DM (Messenger and Instagram) and WhatsApp — Meta’s platform decides, per conversation, whether your outbound message is allowed at all. An inbound message from the recipient opens a 24-hour customer-service window; how long you have left, and what escapes exist once it closes, depends on which channel you are sending to. This page explains the model once instead of per channel, so an integrator reading the MESSAGING_WINDOW_CLOSED error understands what the window is, what the escape hatches are, and which fields to branch on. The per-channel request shapes live on the Messenger and Instagram pages; this page covers the shared semantics. The compliance dimensions this model does not cover (registration, quiet-hours windows, dialing windows) are consolidated on the omnichannel compliance matrix.

1. The window everywhere: Meta DM

Meta’s DM channels (Messenger and Instagram) share one rule, enforced upstream by Meta and pre-checked by Orbit at send time:
  • A recipient’s inbound message (or postback tap) opens a 24-hour window for direct replies.
  • Inside the window, sends pass as messaging_type: RESPONSE (a reply) or UPDATE (a proactive, non-promotional update).
  • Outside the window, the only sends that pass are messaging_type: MESSAGE_TAG carrying a top-level tag, or a one-time-notification token (Messenger only).
The approved message tags Meta accepts on DM channels: Addressing is per-identity-scheme: Messenger replies go to the recipient’s PSID (Page-Scoped ID) and Instagram to their IGSID — both arrive in your inbound webhook payload and are the to of every follow-up. A tag that Meta did not approve, or a MESSAGE_TAG send with no tag, is rejected the same way as an untagged send outside the window.

2. Where it bites in Orbit

Orbit pre-checks the window before dispatch, so a closed window rejects synchronously with 422 MESSAGING_WINDOW_CLOSED instead of a failed send you reconstruct from Meta’s callback:
Read details.hours_since_last_inbound to tell a race (barely past 24) from a quiet conversation (hundreds of hours); details.last_inbound_at is the anchor the recipient’s next inbound message resets. The full error surface, remediation table, and the WhatsApp sibling codes (WHATSAPP_OUTSIDE_24H_WINDOW, WHATSAPP_RE_ENGAGEMENT_WINDOW_CLOSED) are on the troubleshooting page. The OTN exception (Messenger only). A One-Time-Notification token is the single-follow-up escape: you send an OTN request inside an open window, the recipient taps to opt in, and exactly one later send can reference the token and pass even after the window closes — then it is consumed. The request → consume lifecycle, and why OTN is not a campaign primitive, is documented on the Messenger page. First-contact sends are never pre-blocked: with no inbound history there is no window to close, and the untagged send is passed to Meta, which rejects or accepts it under its own rules. Tag first-contact sends yourself.

3. Cross-channel comparison

The WhatsApp window is symmetric in shape but different in mechanics: inside the session you reply free-form; outside it only template messages pass, and sending a template does not reopen the window — only the recipient’s reply does. The WhatsApp page documents the window-status pre-flight endpoint and the template-reply loop. SMS, MMS, and email have no per-conversation messaging window at any layer. Their gates are different planes entirely: A2P registration (10DLC, Sender-ID, DLT) before the first send, plus your own opt-out suppression and quiet-hours settings — comparison on the omnichannel compliance matrix.

4. What Orbit meters on top

The window model is Meta’s; two Orbit-level behaviours sit on top:
  • No delivery receipts. Meta’s Send API never emits DLRs, so Meta DM rows are flagged no_dlr_channel: true on message metadata and resolve to submitted_no_receipt after 5 minutes instead of delivered. On these channels that state is a functional delivery signal, not the ambiguous SMPP case — the distinction, and what to branch on, is on the delivery lifecycle page.
  • $0 wallet behaviour on Messenger. Connecting your own Meta Page makes you the provider of record, so every Messenger send — inside or outside the window, tag or OTN — is free on Orbit’s side and never debits your wallet. Meta bills any Meta-side charges directly. See Messenger → Pricing.
Neither behaviour changes the window rule: a $0 send off-window without a tag still returns 422.

5. What to branch on

Switch on machine-readable fields only:
  • messaging_typeRESPONSE, UPDATE, MESSAGE_TAG on Meta DM sends; the declared relationship between your send and the window.
  • tag — required on MESSAGE_TAG sends; one of the approved tags above.
  • error.codeMESSAGING_WINDOW_CLOSED on Meta DM, WHATSAPP_OUTSIDE_24H_WINDOW on WhatsApp; the channel field on the error tells you which window tripped before you pick a fix.
  • metadata.no_dlr_channel — present on Meta DM message rows, so a submitted_no_receipt reads as Meta’s delivery-guaranteed case.

See also