<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: IGMsg</title>
    <description>The latest articles on DEV Community by IGMsg (@igmsg).</description>
    <link>https://dev.to/igmsg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4236933%2Fcc0a4094-26c6-48f8-bf2c-048a274f3e56.png</url>
      <title>DEV Community: IGMsg</title>
      <link>https://dev.to/igmsg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/igmsg"/>
    <language>en</language>
    <item>
      <title>Comment-to-DM on Instagram's Official API: Webhooks, Private Replies, and Viral Queues</title>
      <dc:creator>IGMsg</dc:creator>
      <pubDate>Thu, 12 Nov 2026 05:35:41 +0000</pubDate>
      <link>https://dev.to/igmsg/comment-to-dm-on-instagrams-official-api-webhooks-private-replies-and-viral-queues-3mp9</link>
      <guid>https://dev.to/igmsg/comment-to-dm-on-instagrams-official-api-webhooks-private-replies-and-viral-queues-3mp9</guid>
      <description>&lt;p&gt;If you have spent any time on Instagram lately, you have seen the ritual: a creator posts a Reel and writes "Comment RECIPE and I'll DM you the link." It works because people will type a keyword faster than they will hunt through a bio. It falls apart the moment the post does well. Unofficial tools that ask for a password or scrape the app are a good way to lose the account you are trying to grow.&lt;/p&gt;

&lt;p&gt;There is an official path. Meta's Instagram Messaging API lets a professional account (Business or Creator) send a private reply to someone who commented on a post, Reel, story, ad, or live broadcast. I spent the last year turning that path into &lt;a href="https://igmsg.com" rel="noopener noreferrer"&gt;IGMsg&lt;/a&gt;, a bootstrapped comment-to-DM tool I built as a ManyChat alternative focused only on Instagram. Here is how the API actually behaves, and the product decisions that fell out of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  You do not poll for comments
&lt;/h2&gt;

&lt;p&gt;The first instinct is to list comments on a media object on a timer. That works for a demo and then you get rate-limited.&lt;/p&gt;

&lt;p&gt;Meta expects you to subscribe to Instagram webhooks — the &lt;code&gt;comments&lt;/code&gt; field, and &lt;code&gt;live_comments&lt;/code&gt; if you care about broadcasts. When someone comments, your server gets the pieces you actually need: the professional account that owns the media, the comment ID, the comment text, the media ID, and the commenter's Instagram-scoped ID and username.&lt;/p&gt;

&lt;p&gt;A few operational details matter more than the happy-path payload. Events can arrive in batches of up to 1,000 updates, but batching is not guaranteed, so handle one at a time. If your endpoint does not return a 2xx quickly, Meta retries for up to 36 hours. Deduplicate on comment ID or you will message the same person twice.&lt;/p&gt;

&lt;p&gt;Public comment replies (&lt;code&gt;POST /{comment-id}/replies&lt;/code&gt;) are a separate call from a private DM. If you want the thread to show "just sent you a DM" so other people comment the keyword too, that is this endpoint, not the Messaging API.&lt;/p&gt;

&lt;p&gt;I match on a keyword the creator has already configured — "link", "recipe", "price" — and ignore everything else. That is not an API requirement. It is how you stay useful instead of DMing every "🔥" on a viral Reel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Private replies are not a normal DM
&lt;/h2&gt;

&lt;p&gt;To send the DM, you POST to the &lt;code&gt;/{ig-user-id}/messages&lt;/code&gt; endpoint on &lt;code&gt;graph.instagram.com&lt;/code&gt; if the creator connected with Instagram login, or the Page &lt;code&gt;/{page-id}/messages&lt;/code&gt; endpoint on &lt;code&gt;graph.facebook.com&lt;/code&gt; if they connected through a linked Facebook Page. The important part is the recipient. You do not address the person by their Instagram-scoped ID for this first message. You pass the &lt;strong&gt;comment ID&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl -X POST &lt;span class="s2"&gt;"https://graph.instagram.com/{version}/{ig-user-id}/messages"&lt;/span&gt; \
  -H &lt;span class="s2"&gt;"Authorization: Bearer {access-token}"&lt;/span&gt; \
  -H &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; \
  -d &lt;span class="s1"&gt;'{
    "recipient": { "comment_id": "{comment-id}" },
    "message": { "text": "Here is the link you asked for." }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three rules from the docs are easy to miss:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You get &lt;strong&gt;one&lt;/strong&gt; private reply to that commenter in this flow. There is no second shot if your copy is wrong.&lt;/li&gt;
&lt;li&gt;You have &lt;strong&gt;7 days&lt;/strong&gt; from when the comment was created — and only while a live broadcast is still running, for live comments.&lt;/li&gt;
&lt;li&gt;The message Meta delivers includes a link back to the commented post. You do not have to invent that deep link yourself.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Where the message lands depends on the relationship: Inbox if they already follow the professional account, or Message Requests if they do not. Unofficial tools that "just log in as you" skip all of this and violate Instagram's terms. We only send through the official Messaging API. The creator connects with Instagram's own login; we never ask for their password.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 24-hour window opens later than you think
&lt;/h2&gt;

&lt;p&gt;This is the confusion I see most often.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;standard messaging window&lt;/strong&gt; is 24 hours, and it opens when the person messages you (or takes a similar action, like tapping a call-to-action in the thread). Inside that window you can keep the conversation going, including a link or an offer.&lt;/p&gt;

&lt;p&gt;A private reply to a comment does &lt;strong&gt;not&lt;/strong&gt; open that window on its own. Meta is explicit: you may send the one private reply, and you may only send follow-up messages if the person replies, and then only within 24 hours of that reply. Story replies and reactions are different. The person already wrote to the account, so the 24-hour window is open and you use the ordinary Send API with their Instagram-scoped ID, not &lt;code&gt;comment_id&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That split is why a comment-to-DM feature and a story-reply feature share a lot of infrastructure but not the same first API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate limits, and what a viral Reel actually does to your server
&lt;/h2&gt;

&lt;p&gt;Official Messaging API limits are per Instagram professional account, not just per app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private Replies&lt;/strong&gt; to comments on posts and Reels: 750 calls per hour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Replies&lt;/strong&gt; to live comments: 100 calls per second.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send API&lt;/strong&gt; for text and links: 100 calls per second (lower for audio or video).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;750 private replies an hour is plenty for a normal launch, and not enough for the Reel that takes off at midnight. If you fire a request the instant each webhook arrives, you will start getting errors in the exact moment the creator needed you.&lt;/p&gt;

&lt;p&gt;The honest implementation is a queue. We accept the webhook, decide whether the comment matches, and enqueue the send. A worker walks the queue under the hourly cap. On a quiet day the DM still goes out in seconds. On a viral day, extras wait and go out as soon as Instagram allows.&lt;/p&gt;

&lt;p&gt;The other product rule is even simpler than the rate limiter: &lt;strong&gt;one DM per person&lt;/strong&gt;. The API already gives you a single private reply in this flow. We also collapse it at the person level, so someone who comments the keyword five times still gets one message. That is courtesy, and it is how you avoid looking like spam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I built a ManyChat alternative
&lt;/h2&gt;

&lt;p&gt;I got tired of watching creators copy-paste the same link and lose the lead in a screenshot, with no idea which Reel made the sale. ManyChat can do comment-to-DM, but it is built for many channels and its price moves with your contact count. I wanted something only about Instagram DMs, on the official API, with flat pricing as the account grew.&lt;/p&gt;

&lt;p&gt;That became IGMsg. A keyword comment can trigger a DM with a link, an offer, or a freebie, plus an optional public reply. Story replies can get the right link. Commenters land on a lead list you can tag, export, or send to Slack and Notion. On paid plans you can continue the thread after someone writes back, attribute Shopify or WooCommerce orders to the post, and see sends, clicks, and sales per Reel.&lt;/p&gt;

&lt;p&gt;It is bootstrapped. We have made about $1,400 in revenue to date and are at $300+ MRR. There is a free plan — 500 DMs a month, three automations, one Instagram account, comment-to-DM and story replies — so you can try it on a real post before you pay. If you would rather use that than build the queue yourself, it lives at &lt;a href="https://igmsg.com" rel="noopener noreferrer"&gt;igmsg.com&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would do if I were starting this weekend
&lt;/h2&gt;

&lt;p&gt;Use webhooks, not polling. Treat &lt;code&gt;comment_id&lt;/code&gt; as the recipient for the first private reply, and do not assume you can send a second message unless they write back. Deduplicate webhook retries. Put a rate-limited queue in front of the Private Replies endpoint before you need it. And cap sends at one per person, even when it is tempting to get noisier.&lt;/p&gt;

&lt;p&gt;The "comment KEYWORD and I'll DM you" format is not going away. The official API is how you keep up with it without borrowing someone's password.&lt;/p&gt;

</description>
      <category>instagram</category>
      <category>api</category>
      <category>automation</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
