The joint Instagram DM and Messenger post covers the two Meta messaging channels side by side — where each starts conversations, what Meta's 24-hour customer-service window allows, and how both run next to SMS and WhatsApp. That comparison answers the whether question. This guide is for the operation that already decided: Instagram is the front door, and the team needs the IG-specific mechanics — the inbound envelope, the handle you actually send to, the story and comment shapes a Messenger-only operator never sees, and the standalone-versus-multichannel cut — without re-deriving them from a pair post.
Everything here describes shipped behavior. The connect flow (Meta OAuth, scopes, webhook subscription) is covered step for step in the Instagram onboarding playbook and the Instagram channel page; this guide does not re-run the setup — it starts where setup ends.
The channel: "instagram" envelope and the IGSID handle
Every inbound Instagram event arrives on one event type: message.received, with channel: "instagram" on the envelope. That is the whole dispatch contract. A plain DM, a story mention, a story reply, and a quick-reply tap all arrive on the same event; you branch on the metadata fields, never on separate Instagram event types — there are none.
{
"event": "message.received",
"channel": "instagram",
"message": {
"from": "<sender_igsid>",
"text": "Is my order shipped?",
"metadata": { "story_mention": { "url": "https://www.instagram.com/stories/..." } }
}
}The one handle that matters is the IGSID — the Instagram-scoped ID in message.from. Three facts drive daily operations:
- The inbound IGSID is the `to` of every outbound DM. Capture it off the inbound event onto the contact record the first time a customer writes in. There is no lookup-by-username on the send path: a send with a missing or empty
tofails withINVALID_RECIPIENT, andusername@brandis not an addressable recipient on this channel. - The connected Instagram account is the sender — resolved from your API key, not a `from` field. One Orbit account can attach several Business or Creator accounts (regional brands, sub-brands); when a conversation comes in, sends address whichever account owns the thread. You never choose a sender per send — the channel entry resolves it.
- The envelope is the same shape SMS and WhatsApp use. The unified inbox, routing, assignment, and SLA clocks treat an Instagram thread exactly like any other channel thread. The IG specifics live in
metadata, not in a separate conversation model.
Two trust properties worth stating in your runbook. Inbound Meta callbacks are signed with Meta's X-Hub-Signature-256 header (HMAC-SHA256 over the raw body keyed with your Meta app secret) — a missing or invalid signature is rejected with 401 INVALID_SIGNATURE before a flow or an agent ever sees the event. And Meta enforces a 200-DM-per-hour ceiling per Instagram account (reduced from 5,000 in February 2026); Orbit counts your sends in a rolling per-tenant window ahead of Meta, so an over-quota send is rejected with RATE_LIMIT_EXCEEDED before it reaches Meta — not after Meta has already logged it against the account.
Story mentions, story replies, and comment-to-DM — the IG-native inbound shapes
Instagram's inbound traffic is not "spaces a Messenger also has." Two shapes are Instagram-native, and one automation pattern is the channel's signature growth play. All three run on IG's own surfaces, not on anything inherited from the parent Meta plumbing.
Story mentions and story replies arrive as ordinary message.received events. A mention — someone tags your account in their story — carries metadata.story_mention.url. A reply to a story carries metadata.story_reply with a url and/or id. Operate them as first-class inbound: in an e-commerce or creator-brand operation a story mention is often the highest-intent inbound of the day (the customer broadcast your brand to their audience); route it into the same inbox with a mention flag rather than letting it blend into the DM queue anonymously.
Comment-to-DM is the automation that turns a public comment into a private thread — the ManyChat-style "comment LINK and we DM it to you" play. On Orbit it is built as a published Flow Studio flow with a `comment_received` trigger node, with optional post filters (specific post/reel ids) and keyword filters (comma-separated, case-insensitive). The guardrails that keep it clean:
- One reply per comment, full stop. Orbit fires the first matching published flow (most recently published wins) and Meta accepts exactly one private reply per comment — the one-shot bound is enforced on both sides, so a retry loop cannot stack DMs on a commenter.
- Private comments carry a 7-day reply window, not the 24-hour DM window. Orbit refuses a send against a comment older than seven days — an archive sweep cannot spray "from the archives" DMs.
- Signature before trigger. Comment events only drive a reply after the
X-Hub-Signature-256check passes; a forged "comment" never reaches the flow. - The DM opens a real inbox thread. The private reply is the first outbound message on a normal DM conversation; an agent or an AI agent continues from there. The automation opens the thread — it does not have to be the whole conversation.
The step-by-step for wiring the flow (connect the professional account, publish the flow, verify the inbound signature) lives in the Meta comment-to-DM guide. The operator takeaway: comment-to-DM is the one inbound shape where you initiate the DM — everywhere else on Instagram, the customer knocks first.
Media-first conversation shapes — running a visual channel
Instagram threads carry more than text, and the send contract shape reveals it: on the outbound message object you provide either `text` or an `attachment` (image / audio / video / file, up to Meta's per-type size caps) — media is a peer of text in the API, not an add-on. Operationally, that changes what a good reply looks like on this channel.
- Answer with the product, not a paragraph. A sizing question earns a photo of the garment on a person; a "where is my order" earns the generic-template card below rather than three sentences. Operators who copy their SMS macros into Instagram threads write walls of text into a visual client and it reads as a dead channel.
- The generic template is Instagram's only structured payload. A generic template is a horizontally scrollable carousel of cards — image, title, subtitle, buttons — requested on a send via two
metadatakeys:template_type: "generic"pluselementsholding the JSON-encoded card array. Because the request ridesmetadata, a malformed or missingelementsdoes not fail the send — it falls back to the plainmessage.text. Log-template sends that "lost their cards" are almost always ametadata.elementsJSON validity problem, not a Meta rejection. - Quick replies are inbound-only. When a customer taps a quick-reply button you presented, the tap arrives as
message.receivedwithquick_reply.payloadpopulated — treat payloads as typed intents in routing, not free text. Attaching quick-reply buttons to an outbound DM is not currently supported by the send API, so do not build a flow that depends on outbound button chips on this channel. - Media failures are visible, but template failures are quiet. Attachment issues fail with an error you can branch on; a fallback-to-text send returns a success-looking receipt. If a media-heavy program sees engagement drop, check that the template sends are still templated.
The window on Instagram — RESPONSE inside, tags outside
Instagram follows Meta's shared customer-service-window rule, and Orbit enforces it at the provider level so a returned success means the message was actually deliverable. The send requires a messaging_type:
messaging_type | When it applies |
|---|---|
RESPONSE | Replying inside the 24-hour window after the customer's last message. |
UPDATE | A proactive, non-promotional update inside the window. |
MESSAGE_TAG | Sending outside the window — requires a tag Meta allows (HUMAN_AGENT, ACCOUNT_UPDATE, POST_PURCHASE_UPDATE, CONFIRMED_EVENT_UPDATE). |
For Instagram-first operations two consequences matter. SLA targets on the IG lane are window math, not business-hour math — a thread that sits past 24 hours expiring without a reply means the next answer needs a HUMAN_AGENT tag, and a mistagged out-of-window send fails instead of silently dropping. And the concept-level model (what separates Meta DM windows from WhatsApp's session/template machinery and from the no-window channels like SMS) is in the joint post's window section and the messaging-window model concept page — this guide deliberately does not duplicate it.
Instagram standalone versus brand-home multichannel commerce
The channel decision for an IG-first brand is not "Instagram or nothing" — it is whether Instagram carries the load alone or fronts a broader commerce stack. The honest cut:
Run Instagram standalone when the brand's customer surface IS Instagram — a creator, a DTC label whose orders start in comments and stories, a drop-driven brand where story mentions and comment-to-DM are the funnel. The full loop (public comment → private reply → DM thread → resolution) fits inside the IG lane, the unified inbox carries it, and SMS remains the fallback for the handful of cases that outlive the window. Costs stay on Meta's per-conversation tiers and the 200/hour ceiling sets the throughput bound.
Run Instagram as the front door to multichannel commerce when the case outgrows the DM thread. The pattern that works: Instagram captures intent (comment-to-DM, story replies), and the conversation hands off to the channel that fits the rest of the case — WhatsApp when a template-heavy, multi-day exchange needs a persistent identifier that survives window expiry; web chat when the case needs a guided flow or form capture; SMS as the always-on fallback that terminates every fallback chain. The joint post's alongside-channel matrix has the full table — the point here is that the hand-off is a routing decision in the same inbox, not a funnel the IG channel owns, and the contact record carries through either way.
The cut is about conversation lifetime, not brand size: if the typical case closes inside a handful of 24-hour windows, standalone Instagram covers it. If cases routinely run days of back-and-forth or need structured hand-offs, put Instagram on the front door and route behind it.
Cross-links, not duplication
The Meta platform packet — connect via OAuth, the shared window mechanics, the side-by-side channel comparison — is deliberately consolidated: setup steps in the Instagram onboarding playbook, send/receive contract in the Instagram channel page, automation wiring in the Meta comment-to-DM guide, and the two-channel comparison in the joint Instagram-and-Messenger post. Keep this guide for the IG-native operation and link out for the shared Meta groundwork, so the two page families disagree as little as possible when the platform rules move.
Frequently asked questions
Do story mentions and comment-to-DM need separate event subscriptions?
No. Both arrive as message.received on the standard inbound webhook with channel: "instagram" — story mentions and replies branch on metadata.story_mention / metadata.story_reply, and comment-to-DM fires from a published comment_received flow. There are no dedicated instagram.story.* event types to subscribe to.
What identifier do I send to — the user's Instagram handle?
No. Sends address the recipient's IGSID (Instagram-scoped ID), captured from the inbound message.from. A missing or empty to is rejected with INVALID_RECIPIENT. The connected Instagram account supplies the sender side; there is no from field.
Can I attach quick-reply buttons to an outbound Instagram DM?
Not currently. Quick replies are inbound-only on the send path — a customer's tap arrives with quick_reply.payload on message.received. For outbound structured content, the generic-template carousel (via metadata.template_type + metadata.elements) is the supported shape.
What stops a comment-to-DM flow from spamming?
Three bounds stack: a forged comment never reaches the flow because the inbound webhook signature is checked before evaluation; only published flows with a comment_received trigger match, and only the first matching flow fires; and the comment must be under seven days old or the send is refused. One commenter gets at most one auto-reply, and an opt-out surfaces as a failed send the flow log records.
How does the 200 DM/hour Meta cap interact with the 24-hour window?
They are orthogonal. The window gates WHEN a reply type is allowed (RESPONSE inside, tags outside); the hourly cap gates HOW MANY sends the account can perform. Over-quota sends are rejected with RATE_LIMIT_EXCEEDED before reaching Meta, so a campaign burst inside open windows still has to pace against the rolling per-tenant counter.
The takeaway
Instagram DM earns a standalone operator guide because its work is not "Messenger on a different Meta surface": the IGSID handle, the metadata-carried story shapes, the published comment_received flow that turns a comment into a private thread, the text-or-attachment send contract, and the generic-template carousel are all IG-specific, and they are all live behind the same unified inbox as every other channel. Run it standalone when the IG lane closes cases inside the window; run it as the front door to multichannel when cases outlive it. For the shared Meta platform groundwork — connect, windows, the two-channel comparison — the joint post and the onboarding playbook carry it, so this guide stays focused on operating the Instagram lane.
Published 28 September 2026.