Instagram Messaging API: DMs, Rules, and Limits
The Instagram Messaging API lets a professional account read and reply to DMs through Meta's Graph API. The user has to message first. You then have 24 hours to reply, or 7 days for a human using the human agent tag. Personal accounts aren't supported. Adeli reads and replies to DMs on connected accounts and never sends unsolicited messages.
The Instagram Messaging API is the part of Meta's Instagram API that lets a professional account read and reply to Instagram Direct messages from your app. It's reply-first by design: the person has to message the account before your app can send them anything. After that, three timing rules decide what you can send. Design your inbox around them before you write any send code.
- The 24-hour window. You can reply freely for 24 hours after the user's last message.
- The human agent tag. A human can reply for up to 7 days.
- The private reply. One message to someone who commented, within 7 days of the comment.
Break any of them and the Send API returns error code 10, subcode 2534022: "This message is sent outside of allowed window."
What is the Instagram Messaging API?
It's a set of Graph API endpoints and webhooks for Instagram DMs. Your app gets new messages as webhooks, reads conversations through the Conversations API, and sends replies with a POST to the account's /messages edge. All of it runs on accounts that have connected to your app (Messaging API docs).
Here's what you can send:
| Type | Formats | Max size |
|---|---|---|
| Text | UTF-8 | 1,000 bytes |
| Image | PNG, JPEG | 8 MB |
| Video | MP4, OGG, AVI, MOV, WEBM | 25 MB |
| Audio | AAC, M4A, WAV, MP4 | 25 MB |
| File | 25 MB |
You can also send links, reactions, the like_heart sticker, templates, and shares of posts the account owns. Group messaging is not supported. The webhook fields are messages, messaging_postbacks, messaging_reactions, messaging_seen, messaging_referrals, and messaging_optins.
A text reply looks like this. The recipient is the Instagram-scoped ID (IGSID) from the incoming webhook, not a username:
curl -X POST "https://graph.instagram.com/v25.0/<IG_ID>/messages" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"recipient": { "id": "<IGSID>" },
"message": { "text": "Thanks for reaching out. Your order has shipped." }
}'Instagram Login vs. the Messenger Platform for Instagram
There are two ways to build Instagram messaging, and they differ by login. The Instagram API with Instagram Login connects the account directly. The Messenger Platform route goes through a Facebook Page linked to the Instagram account. Both serve professional accounts only.
| Instagram API with Instagram Login | Messenger Platform for Instagram | |
|---|---|---|
| Facebook Page needed | No | Yes, linked to the account |
| Host | graph.instagram.com |
graph.facebook.com |
| Token | Instagram User access token | Page access token |
| Permissions | instagram_business_basic, instagram_business_manage_messages |
instagram_basic, instagram_manage_messages, pages_manage_metadata |
Sources: the Instagram Login messaging docs and the Messenger Platform get-started guide. Meta's own guide says that if a user has no linked Page, you should use Instagram Login instead.
Can a business send the first DM?
No. Meta's docs say your app can message someone "only after" that person has messaged the professional account. There's no cold outreach through the API. A business can't start a thread with a follower or a lead.
The one exception is the private reply. When someone comments on the account's post, Reel, story, Live, or ad, your app can send that person one DM, within 7 days of the comment (Live comments only during the broadcast). If they write back, you can keep going, within 24 hours of their response.
curl -X POST "https://graph.instagram.com/v25.0/<IG_ID>/messages" \
-H "Authorization: Bearer <ACCESS_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"recipient": { "comment_id": "<COMMENT_ID>" },
"message": { "text": "Sending you the link here." }
}'Private replies use the comments permissions (instagram_business_manage_comments on Instagram Login), not the messaging ones, and the comment ID comes from the comments webhook. The Instagram API comments guide covers reading and moderating comments.
What is the 24-hour messaging window?
It's the period after a user's message in which your app can reply freely. Meta's messaging policy gives businesses up to 24 hours to respond after a user contacts them, and messages in that window can include promotional content. Each new message from the user restarts the clock.
Once the window closes, a normal send fails with code 10, subcode 2534022 (error codes). Plan for it in three places:
- Queue by deadline. Track the timestamp of each user's last message and sort your inbox by how much window is left, not by arrival time.
- Don't retry 2534022. It isn't transient. Retrying the same message won't work until the user writes again.
- Automate early. Bots and auto-replies have to finish inside 24 hours. Anything slower needs a person.
What is the human agent tag?
It's a message tag that lets a person reply outside the 24-hour window, for up to 7 days. Meta's policy describes it as allowing businesses to manually respond to user messages within a 7-day period. The Instagram Login messaging docs confirm your app can tag a response to send it outside the 24-hour window.
The tag covers manual replies only, from a person who needs more time, like a support rep chasing a refund. Using tags outside their approved use cases can get your ability to send messages restricted, so don't put the tag on automated follow-ups or promotions.
| Rule | How long | Who can send | What's allowed |
|---|---|---|---|
| Standard window | 24 hours from the user's last message | Your app, automated or human | Any message, including promotional |
| Human agent tag | Up to 7 days | A human only | Manual replies |
| Private reply | 7 days from the comment | Your app | One message to the commenter |
Meta's policy also notes that some message tags are only available on the Messenger Platform and not on the Instagram Messaging API, so check that a tag is supported for Instagram before you build on it.
Which permissions does the Instagram DM API need?
On Instagram Login, instagram_business_basic and instagram_business_manage_messages. On the Messenger Platform route, instagram_basic, instagram_manage_messages, and pages_manage_metadata. The Instagram API permissions guide lists every scope across both logins.
You also need the right access level. Standard Access covers accounts you own or manage and people with a role on your app. That's why messaging often works for your testers and then fails for your first real customer. Serving accounts you don't own needs Advanced Access, which means App Review and Business Verification. Our guide to how long Meta app review takes covers the timeline.
What are the Instagram Messaging API rate limits?
Limits are per Instagram professional account, and they vary by endpoint. From Meta's rate limiting docs:
| Endpoint | Limit per account |
|---|---|
| Conversations API | 2 calls per second |
| Send API: text, links, reactions, stickers | 100 calls per second |
| Send API: audio or video | 10 calls per second |
| Private replies to posts and Reels | 750 calls per hour |
| Private replies to Live comments | 100 calls per second |
Meta's docs conflict here. The same page lists 300 calls per second for text sends in its "Messenger API for Instagram" section, so plan for 100 to be safe. Hitting a limit returns code 613, subcode 2534040, "Calls to this api have exceeded the rate limit". Pause and retry later. The Instagram API rate limit guide covers the other limits.
Is the Instagram DM API free?
Meta documents no per-message charge for replying to Instagram DMs through the API. The cost is in setup: building webhooks, passing App Review for Advanced Access, completing Business Verification, and keeping every account's token fresh. Is the Instagram API free? adds those costs up.
How do I handle Instagram DMs with Adeli?
Adeli reads and replies to the DMs your connected accounts receive through the messaging API, the same API you publish with. Adeli holds the Meta developer app, went through Meta's review, and refreshes every connected account's tokens. You hold one API key.
Adeli does not send outbound or unsolicited messages, which matches Instagram's own rule that the user writes first. Your app still owns the timing, so track the 24-hour window on your side. The Adeli messages docs cover the endpoints, and Adeli for Instagram covers publishing. Your first 3 connected accounts are free.