Instagram Persistent Menu API: The Always-On DM Button That Can Silently Go Stale (2026)
The Persistent Menu is the one Instagram DM object that stays on screen for the entire conversation — hours, catalog, a human handoff. Setting it is a single API call. Keeping it accurate is the part most chatbot and scheduler builds get wrong.
What makes this object different
Ice Breakers only show before a person’s first message. Quick Replies and the Generic Template attach to a single message and disappear after use. The Persistent Menu is different — once set, it stays visible for the life of the conversation. A tap sends a postback webhook to your server and opens the same 24-hour standard messaging window that gates every other Instagram DM automation.
Only two button types are supported
Postback Button
Sends a fixed payload string to your webhook when tapped — used to route into a bot flow such as “Talk to an agent” or “Track my order.”
URL Button
Opens a web page inside Instagram’s in-app browser. There is no phone-call button and no nested submenu on this object.
What’s missing compared to a Messenger-first build
Meta’s own documentation explicitly calls out three parameters that are not available on the Instagram version of this object: composer_input_disabled, webview_height_ratio, and any way to customize the menu per recipient. A bot template or build spec written against Messenger’s classic persistent menu first will reference all three — and none of them do anything when ported over to Instagram.
The trap: menu updates are not real time. Existing conversations keep showing the old menu until the person manually refreshes their inbox. Only brand-new conversations pick up an updated menu automatically. Meta’s own guidance is direct about this: the app has to handle someone tapping a menu item that was already removed on your side, because there is no push mechanism that forces every open thread to refresh at once.
Setting, reading, and removing the menu
The menu is managed through the same /messenger_profile endpoint used for Ice Breakers, with platform set to instagram and a persistent_menu array. Each entry carries a locale and a call_to_actions list, so one account can serve a different menu per language — useful for an international support bot, and one more place a locale mismatch can quietly leave a stale menu showing for the wrong audience.
| Action | Method | Endpoint |
|---|---|---|
| Set menu | POST | /IG_ID/messenger_profile |
| Read menu | GET | /IG_ID/messenger_profile?fields=persistent_menu |
| Remove menu | DELETE | /IG_ID?fields=persistent_menu |
Meta’s guidance recommends staying selective — around five items for a usable menu — but that is a usability recommendation written into the docs, not an enforced ceiling the way Ice Breakers are hard-capped at four questions.
Where this fits a scheduler or support-bot build
For a SaaS scheduling tool or chatbot platform connecting client accounts to Instagram DMs, the Persistent Menu is usually the first thing a user sees — before any Ice Breaker or Quick Reply flow runs. Getting the access tier, the instagram_business_manage_messages permission, and the webhook subscriptions right is the same App Review work already required for Instagram messaging generally; the menu is simply one more object competing for that same access grant.
Related reading: Instagram Messaging API Approval covers the permission and webhook setup this menu depends on, Instagram DM Quick Replies, Ice Breakers, and the Generic Template covers the other message-level objects in the same conversation, and the Instagram App Review service page covers submission support for the underlying permissions.