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.

ActionMethodEndpoint
Set menuPOST/IG_ID/messenger_profile
Read menuGET/IG_ID/messenger_profile?fields=persistent_menu
Remove menuDELETE/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.