Persistent Menu
The Persistent Menu brings users directly into the top-level features and flows in your bot.

Contents
Setting the Menu
You must set up a Get Started button if you also wish to use persistent menu.
Set the menu using a POST request:
curl -X POST -H "Content-Type: application/json" -d '{
"persistent_menu":[
{
"locale":"default",
"composer_input_disabled":true,
"call_to_actions":[
{
"title":"My Account",
"type":"nested",
"call_to_actions":[
{
"title":"Pay Bill",
"type":"postback",
"payload":"PAYBILL_PAYLOAD"
},
{
"title":"History",
"type":"postback",
"payload":"HISTORY_PAYLOAD"
},
{
"title":"Contact Info",
"type":"postback",
"payload":"CONTACT_INFO_PAYLOAD"
}
]
},
{
"type":"web_url",
"title":"Latest News",
"url":"http://petershats.parseapp.com/hat-news",
"webview_height_ratio":"full"
}
]
},
{
"locale":"zh_CN",
"composer_input_disabled":false
}
]
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=YOUR_ACCESS_TOKEN_HERE"
Fields
| Property Name | Description | Type | Required |
|---|---|---|---|
| Locale of the menu. We will show this menu when user locale matches the provided locale.
You must at least specify a menu for the | String | Y |
| Set to | Boolean | N. If this field is not specified, it will default to |
| Top-level menu items that user can interact with. | Array of | Either |
Caveats:
call_to_actionsis limited to 3 items for the top level, and 5 items for any submenus.- In Messenger, your bot's menus are cached but updates are fetched each time they're loaded. If you update the menu, trigger the fetch by loading it and then reload to see your changes.
menu_item object
| Property Name | Description | Type | Required |
|---|---|---|---|
| Value is | String | Y |
| Button title | String | Y |
| For | String | Y, if type is |
| For | String | Y, if type is |
| Nested menu_item that will be expanded in next level. | Array of | Y, if type is |
| Height of the Webview. Valid values include | Enum | N |
| Must be | Boolean | N |
| URL to use on clients that don't support Messenger Extensions. If this is not defined, the | String | N |
| Set to | String | N |
Caveats:
titleis limited to 30 characterspayloadis limited to 1000 characterscall_to_actionsis limited to 5 for sub-levels- You can have at most 3 hierarchical levels of
menu_itemin total
Response
If your menu was set successfully, you will get back the following response:
{
"result":"success"
} Reading the Menu
In order to get the menu you set previously, send a GET request:
curl -X GET "https://graph.facebook.com/v2.6/me/messenger_profile?fields=persistent_menu&access_token=PAGE_ACCESS_TOKEN"
Deleting the Menu
In order to remove the Persistent Menu from your bot, send a DELETE request:
curl -X DELETE -H "Content-Type: application/json" -d '{
"fields":[
"persistent_menu"
]
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=PAGE_ACCESS_TOKEN" This will delete your menu for all locales. Users will see only the normal message composer when they enter your bot.
Testing Tips
Bots' menus are cached locally, but updates are fetched periodically. If you update the menu while testing, you can force this fetch to happen by deleting the bot's thread and then beginning a new one.
In order for users to see your menu the following must be true:
- The user must be on Messenger v106 or above on iOS or Android.
- The page the bot is attached to must be published.
- The bot must be set to "public" in the developer console.
- The bot must have passed the approval process for
pages_messagingpermissions.