Handover Protocol

Developers who want to use Handover Protocol or have been using Previous version of Handover Protocol must refer to the recent improvements and behaviors we have introduced to Handover Protocol. All Pages will be migrated to support the new Handover protocol behaviors starting March 14th, 2022. All apps are highly encouraged to refer to the breaking changes section in the developer doc and implement the necessary changes before the deadline.

The Messenger Platform's handover protocol enables two or more Facebook apps to participate in a conversation by passing control of the conversation between them. This feature can be used in many ways to enrich your Messenger experience. There are 3 common use cases for Handover Protocol.

  1. A business wants to use an automated experience for simple FAQs but wants to transfer the customer to a live support agent for complex inquiries. In this case the automated experience and live agent experiences are powered by 2 different apps.
  2. A business wants to run a marketing campaign and wants to use an automated experience to qualify leads or provide product recommendations based on product quiz. After the lead qualification, the business would like to use Facebook Page Inbox to follow up with the prospect.
  3. A business wants to run a marketing campaign and send prospects to a specific Messenger experience but do not want the customer support agents on the business page to be distracted by messages coming from the campaign.

In the below sections, we will cover how you can use Handover Protocol to enable use cases like the ones above.

Handover protocol will be enabled by default for all apps connected to a Facebook page.

Note: In the below content you will see references to “Previous HOP” and “New HOP”. New HOP refers to the Handover Protocol specifications introduced as of Sept 14th, 2021.

Required Permissions

A page access token with pages_messaging permission is required to interact with Handover Protocol endpoints or subscribe to webhooks.

Apps in Development Mode, are restricted to message people that have a role in the app. Additionally, Pages in unpublished status will only be allowed to message people with a role on the Page.

The Page Admins can change the role of their app at any time (primary or non-primary)

Using the Handover Protocol

To familiarize yourself with Handover protocol, we have summarized the key actions you could take.

Subscribe apps to your page

Retrieving the list of non-primary receiver apps

Only the Facebook app with the Primary Receiver app role may retrieve the list of all messaging apps connected to the page. To programmatically retrieve the list of apps for your Page, send a GET request to the Messenger Platform with the page token of the Primary Receiver app:

Example Request:

curl -X GET "https://graph.facebook.com/v12.0/me/secondary_receivers?fields=id,name&access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{
   "data":[
      {
         "id":"12345678910",
         "name":"David's Composer"
      },
      {
         "id":"23456789101",
         "name":"Messenger Rocks"
      }
   ]
}

Assigning Primary receiver role

Optionally, the Page admin can assign one of the connected apps to be the primary receiver for the Page.

  • If a Primary app is configured, by default all new threads will be sent to the Primary Receiver app. Else, all apps will get the message and any one of them can respond to the thread but they wouldn’t get exclusive control. For exclusive control an app needs to call the take thread control API - detailed in the API section below.
  • Primary app is the only app that will be allowed to take thread control from any other app via the Take Thread Control API
  • Primary app can be setup from Page settings > Messenger Platform > Connected Apps > Configure as below:

Subscribe to Webhook events

To help you manage your use of the handover protocol and track when control of the conversation is passed between Facebook apps, the Messenger Platform offers the following set of specialized webhook events.

messaging_handovers event

The messaging_handovers webhook event is sent to the webhook associated with a Facebook app any time one of the following handover protocol actions is taken on that app:

  • Thread control is passed to the app
  • Thread control is taken from the app
  • Thread control is requested from the app
  • Metadata is passed to the app
  • App role is changed

Standby event

Apps that don't have the thread control at the time can optionally subscribe to a separate 'standby' channel to listen to incoming messages. It is important to implement the standby channel, as it allows apps to track the full context of the conversation and be well-informed on how to proceed if control is passed to them.

These subscriptions can be done via the app dashboard. Go to the App dashboard > Messenger > Settings > Webhooks > Edit. An example is below:

Changing app roles

Whenever a page admin changes an app’s role to Primary the following messaging_handover_event would be sent to all the apps

Example messaging_handovers Event: app_roles:

  {
   "id":"<PSID>",
   "timestamp":1458692752478,
   "app_roles":{
      "123456789":[
         "primary_receiver"
      ]
   }
}

Pass thread control

The Pass Thread Control API is used to pass control of a conversation between apps. The calling app can pass optional metadata along with the API request. When thread control is passed to an app, the pass_thread_control webhook event will be sent to this app along with any optional metadata.

All apps can use this API to pass the thread control to another app.You can also enable live chat in your bot by passing thread control directly to the Page inbox.

Example Request:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "target_app_id":123456789,
  "metadata":"String to pass to receiver app" 
}' "https://graph.facebook.com/v12.0/me/pass_thread_control?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Example messaging_handovers for pass_thread_control:

{
   "sender":{
      "id":"<PSID>"
   },
   "recipient":{
      "id":"<PAGE_ID>"
   },
   "timestamp":1458692752478,
   "pass_thread_control":{
      "previous_owner_app_id":"<previous_app_id or null (idle_mode)>",
      "new_owner_app_id":"123456789",
      "metadata":"Additional content that the caller wants to set"
   }
}

We highly recommend businesses to notify users when the user is transferred from human agent-based experience to an automated experience. This is legally mandated in certain jurisdictions. We also recommend that users be notified when they are being transferred from one app to another. To create an even better user experience, implement Personas to make it easy for users to understand if the message was sent by an automated experience or via a human agent.

Passing Thread Control to Facebook Page Inbox

The handover protocol can be used to pass thread control from an app to your Facebook Page Inbox. This allows you to offer live chat by replying to messages sent to the Facebook Page Inbox and is also useful as a fallback if your bot is unable to understand a message.

To enable live chat via Page Inbox, do the following:

  1. From the current controlling app, pass thread control to the Facebook Page Inbox by setting the target_app_id property of the request to 263902037430900 (appid of Facebook Page Inbox).

When Facebook Page Inbox is not the controlling app, all messages sent to your bot will appear in the 'Done' folder by default. When Facebook Page Inbox has control of the conversation, all messages from the conversation will be moved to the 'Inbox' folder.

Starting Graph API v12.0+, if your app is subscribed to the echo webhook, you will get a webhook with Facebook Page inbox app_id that indicates that the message reply is coming from Facebook Page inbox. The recommendation is to have your app use the pass thread control API to pass control back to Page inbox by setting the target app id as 26390203743090. This is a better experience for the user since other apps connected to the Page won’t interject the conversation the business might be having with the customer.

Returning control from Facebook Page Inbox to Idle Mode

Once Facebook Page Inbox conversation is done, the control can be released by clicking the ‘Done’ checkmark for the conversation. If a Primary app is set, the thread would pass to the primary app, else the thread would be released to idle mode.

Pass metadata between apps

There may be scenarios where apps may need to pass additional data to other apps connected to the page without passing or taking thread control.

For example, a page is connected to 2 apps. One of them is an automation app to respond to simple inquiries and other is a customer service platform which customer support agents use to respond to complex inquiries. If the support agents update the status of the case or needs to transfer the case to another department, the customer service platform might want to pass this additional context to the automation app without passing control to the automation app. That way the automation app can accurately report on reduction in customer wait times, average handle time for case etc.

We are introducing the Pass Metadata API for use cases like the one outlined above. A call to this API specifying the target_app_id would ensure that the target app would receive a webhook event with the metadata from the calling app.

Example Request:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "target_app_id":123456789,
  "metadata":"additional content that the caller wants to set" 
}' "https://graph.facebook.com/v12.0/me/pass_thread_metadata?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Example messaging_handovers for pass_metadata:

  
{
  "sender":{
    "id":"<PSID>"
  },
  "recipient":{
    "id":"<PAGE_ID>"
  },
  "timestamp":1458692752478,
   "pass_metadata":{
    "caller_app_id":123456789,
    "metadata":"additional content that the caller wants to set"
  }
}

Take Thread Control

The handover protocol can be used to pass thread control from an app to Facebook Page inbox. This allows you to offer live chat by replying to messages sent to Facebook Page inbox and is also useful as a fallback if your bot is unable to understand a message.

Take Thread Control API allows the app with the Primary Receiver role to take control of the conversation from the other apps. This is useful if it takes too long for the other apps to respond or becomes unresponsive. An optional metadata string may also be sent in the request.

The previous owner app will receive a messaging_handovers webhook event when control of the conversation has been taken away. The event will contain the metadata string.

Example Response:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "metadata":"String to pass to the current controlling app" 
}' "https://graph.facebook.com/v12.0/me/take_thread_control?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Example messaging_handovers for take_thread_control:

{
  "sender":{
    "id":"<PSID>"
  },
  "recipient":{
    "id":"<PAGE_ID>"
  },
  "timestamp":1458692752478,
  "take_thread_control":{
    "previous_owner_app_id":"123456789", //could be null if thread was in idle mode
    "new_owner_app_id": <new_app_id>,
    "metadata":"additional content that the caller wants to set"
  }
}  

Taking Thread Control From Facebook Page Inbox

For Messenger experiences that enable live chat via Facebook Page Inbox, the handover protocol allows the Page admin to manually initiate a take thread control event by moving the conversation from 'Done' to the 'Inbox'. It is important to note that the thread would immediately be passed to Facebook Page Inbox irrespective of the current app’s role.

Extending Thread Control

The Extend Thread Control API will allow any app currently in control of the thread to extend its expiration time to idle Mode. The duration is specified in seconds in the API call as below. A max of 7 days can be set as the duration in one call:

Example Request:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "duration": 86400, // in seconds 
}' "https://graph.facebook.com/v12.0/me/extend_thread_control?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Request Thread Control

The Request Thread Control API allows an app to notify another app currently in control of the thread that it wants control of the chat. The controlling app can choose to pass the thread control or do nothing. An optional metadata string may also be sent in the request. If the thread is however in Idle mode, the control of the thread will directly be passed to the requesting app.

The flow for using the Request Thread Control API looks like this:

  1. The non-controlling app calls request_thread_control.
  2. If thread is in idle mode, control of thread passes to the requesting app, and it receives a messaging_handovers event with the pass_thread_control property.
  3. If thread is not in idle mode, the controlling app receives a messaging_handovers webhook event with the request_thread_control property.
  4. The controlling app calls pass_thread_control to pass control to the Secondary Receiver that called request_thread_control.
  5. The requesting app is given control of the chat and receives a messaging_handovers event with the pass_thread_control property.

Example Request:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "metadata":"additional content that the caller wants to set" 
}' "https://graph.facebook.com/v12.0/me/request_thread_control?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Example messaging_handovers for request_thread_control:

  
{
   "sender":{
      "id":"<USER_ID>"
   },
   "recipient":{
      "id":"<PSID>"
   },
   "timestamp":1458692752478,
   "request_thread_control":{
      "requested_owner_app_id":"123456789",
      "metadata":"additional content that the caller wants to set"
   }
}  

Releasing Thread Control

The Release Thread Control API can be used to by any app to release their control of the thread whenever they are done with their flow. It is always considered best practice to release thread control when it is no longer needed rather than waiting for 24 hours to let the thread go into idle mode automatically.

Example Request:

curl -X POST -H "Content-Type: application/json" -d '{
  "recipient": {
    "id": "<PSID>"
  },
  "metadata":"additional content that the caller wants to set" 
}' "https://graph.facebook.com/v12.0/me/release_thread_control?access_token=<PAGE_ACCESS_TOKEN>"

Example Response:

{"success":true}

Get Thread Owner

The handover protocol's Thread Owner API returns the app ID of the app the currently has thread control for a Page. This is useful for bots that have complex implementations of the handover protocol, where an app's actions are dependent on whether it currently has thread control. The Thread Owner API may be called by apps that are Primary as well as Non-Primary receivers.

On success, the Messenger Platform will return the thread_owner object with the app_id of the app that currently has thread control along with expiration time for that app in the body of the response. However, if the thread is not owned by any app i.e thread is in Idle mode, the app_id field in the response would be null and the expiration field would not be present.

Example Response:

curl -X GET "https://graph.facebook.com/v12.0/me/thread_owner?recipient=<PSID>&access_token=<PAGE_ACCESS_TOKEN>"
{
   "data":[
      {
         "thread_owner":{
            "app_id":"<APP_ID>", //App Id of current thread owner app, null if thread Idle
            "expiration":1234567 //Time after which thread will go into Idle mode. Field would not be present. if thread is currently idle
         }
      }
   ]
} 

Note:

  • If the app making the above API call is Primary, the response would contain the app Id as well as expiration of the thread owner app.
  • If the caller is a non-primary app, the app Id will have their value if the thread is owned by them, else it would be null
  • If the thread is in idle mode the app Id would always be null in the response.
  • The expiration field would only be included if the thread is not in idle mode i.e. thread is owned by an app currently.

Key Handover Protocol behaviors

Exclusive Mode

Whenever an app is in control of the thread, no other app would be able to interject the conversation by sending messages to the thread. A controlling app will have exclusive control of the thread. A Primary app would also not be able to interject a conversation, if it needs to interact with the user, it must take control of the thread.

The non-controlling apps would still be able to listen to all webhook events on the standby channel for analytics/debugging/tracking purposes.

If another app is in control of the thread and any other app tries to message the user an error message as below would be sent back with HTTP Status: 400 Bad Request

{
   "error":{
      "message":"(#10) Message failed to send because another app is controlling this thread now.",
      "type":"OAuthException",
      "code":10,
      "error_subcode":2018300,
      "fbtrace_id":"AQ2lKD7UqnvqCrMs16fUNLk"
   }
}

Idle Mode

In idle mode, any app can claim ownership of the thread and start interacting with the user. HOP allows apps to send messages to a thread in idle mode.

The following scenarios are when you should expect a thread to be in idle mode or non-controlled mode:

  • When Primary app is not set, all threads start in idle mode.
  • After thread ownership expiration (default expiration time is 24 hours of inactivity after an app takes control)
  • The controlling app explicitly releases their ownership

If a Primary app is set and a user messages a page when thread is idle, then the Primary app gets the control of the thread. If no Primary app is set all the apps would receive the message and can respond. If exclusive control is needed the desired app needs to use the take thread control API to take control of the thread from idle mode.

Human Agent Tag

Apps with Human Agent tag permission will be able to interject the conversation the user might be having with another app. One of the common use cases for this is when the user is stuck in a conversation with an automation app and the agent needs to intervene. When the app with the Human Agent tag permission interjects the conversation, the thread control is passed to the Human Agent app.

When you are not in control of the thread, please use this tag only when you see genuine cases of intervention and when you have ascertained 100% that you have to take control. We would be monitoring the use of this tag for any misuse or violation.

Postback CTA

  • If a user clicks on a postback CTA (on a message or the menu) that was generated in thread by app A
  • If thread is owned by app B, thread control will pass to app A with the CTA payload as the pass control metadata. This is done since app A is configured to handle that postback unlike app B which may error out.
  • If thread is in idle mode, thread will remain idle.
  • If thread is owned by app A, thread will remain with app A.

With the New HOP, the postback events will be sent to the standby channel for all non-controlling apps, and to the messaging channel for the controlling app.

Persistent Menu

  1. If primary app is set, only primary app will be able to set/delete page level menu. Otherwise any apps can set page level menu.
  2. The controlling app will be able to set/delete user level menu regardless of primary app settings
  3. Any app can set user level menu when thread is in idle mode
  4. Unlike Previous HOP, postback events from any of the menus will be sent to the standby channel for all non-controlling apps, and to the messaging channel of the controlling app.
  5. Also in case a user taps a menu item on a menu that was set by another app, thread control will pass to that app that set the menu in the first place. If thread is in idle mode, the thread will not pass, it will only happen when thread is owned by an app (Same as Postback CTA behavior above).

Default Behavior (Without utilizing Handover Protocol)

By default, if no app takes control of the thread all subscribed apps may respond at any given time. All apps would be receiving the messages and events on the messaging channel. If primary app is set events will be received on the messaging channel by the primary app and on the standby channel for other apps. Primary app will get the thread control by default.

However, if there is no primary receiver set, other apps can take thread control by calling the Take Thread Control API. The app which calls the Take Thread Control api first will get the control of the thread.

Handover Protocol API availability based on app type

The following is a summary of the available actions for Primary and other apps. For more information and usage details on each handover protocol action, see below this section.

Primary Apps

Non-Primary Apps

Page Inbox

Pass Thread Control

Take Thread Control

Standby Channel

Request Thread Control

Extend Thread Control

Release Thread Control

Pass Metadata

Get Secondary Receivers List

Get Thread Owner

Migration Guide

If you already use handover protocol today, here is a summary of the changes you need to account for given the improvements we are introducing to Handover protocol.

Property Previous HOP Handover Protocol Improvements as of 9/14/2021

Apps setup for HOP

Apps must be assigned a primary or secondary role upon adding to the page to enable HOP.

Roles are optional to enable HOP. Brand can choose to assign an app as primary if needed.

Entry points

Always default to primary app.

Any entry point can be associated with an app. CTM to start with.

Exclusivity

Any app can respond at any time & make changes to the thread (ex: Updating menu).

Only controlling app can respond and make changes to the thread. If needed, a primary app can take control of the thread.

Facebook Page Inbox

  1. Marking conversations Done releases thread to Primary app
  2. Transferring conversation from Done to Inbox would request control from Primary app
  1. Marking Done releases thread to Primary app if it is set, else releases to idle mode
  2. Transferring to Inbox would take thread control from any app

Secondary app powers

Cannot pass control to another secondary app

Not applicable since there are no secondary apps. Any app can pass control to any other app, irrespective of roles.

Thread ownership expiration

Never expires

Goes into "idle mode’ when either conditions are met 1) 24 hours of inactivity OR 2) Controlling app releases control. Any app can take ownership in idle mode.

Extend Thread control API

Not available

Allows an app to extend thread ownership time with an user

Release Thread Control API

Not Available

Allows an app to release thread ownership with an user.

Pass Metadata API

Not available

Allows an app to send additional metadata to another app.

Thread Owner API

Just retrieves app_id of thread owner

app_id and expiration time of thread will be included in thread. app_id will be null when thread is in idle mode

Webhook events

Some events are sent on messaging and some events on standby channels for Secondary apps.

All events would be sent on standby channel for non-controlling apps.

pass_thread_control event

Did not have the previous_owner_app_id

Will have the previous_owber_app_id

take_thread_control event

Did not have the new_owner_app_id

Will have the new_owner_app_id

Postback CTA behavior

No ownership change happens when postback CTAs are clicked

Please check Postback CTA behavior

Possible breaking changes:

  • In Previous HOP, assigning primary and secondary roles to apps will enable handover protocol. All messages received by the page will be sent to all the apps connected to the page via the messaging channel. Also, in Previous HOP there is no requirement for apps to subscribe to standby or messaging_handovers webhook events. In new HOP, handover protocol would be enabled for the pages by default. So, it's important that apps subscribe to standby and messaging_handover events to get context of the conversations if needed.
  • If any of your apps have been messaging the thread without having control, that would start failing in HOP V2 unless thread is in Idle mode. Ensure that you handle this scenario correctly (Exclusivity).
  • Ensure that you handle Idle mode correctly: - In Previous HOP there was no concept of a thread going to idle. So, review areas where you expect to message the thread after 24 hours. If you need longer control, use the Extend Thread Control API. - When thread is in idle mode and a user messages the page, if Primary app is set, the thread will go to the Primary app. - Ensure that you call Get Thread Control API to check current thread owner and expiration before taking an action
  • All events for the apps that are currently not in control of the thread will come on the standby channel. Previously some events like Persistent menu payloads as well as the take_thread_control event came on the messaging channel irrespective of whether an app is in control of the thread or not. This is fixed in the New HOP.
  • If a person uses Facebook Page Inbox to message the thread, the control will automatically pass to Facebook Page Inbox, even from Primary apps.

Migration steps from Previous HOP to New HOP:

As part of the New HOP launch, Previous HOP and new HOP will both exist until March 14th, 2022. To ensure that your app doesn’t break when talking to an app which has not yet moved to new HOP, please follow the below mentioned steps:

  • Use the new Feature Status API to determine if a page is on Previous HOP or New HOP:
curl -X GET "https://graph.facebook.com/v12.0/me?fields=messaging_feature_status&access_token=<PAGE_ACCESS_TOKEN>"

After determining if Page is on Previous HOP or New HOP:

For pages still on Previous HOP:

  • Maintain your Previous HOP logic and switch to this logic based on the determination above.
  • Follow:
    • Do not call any of the New HOP APIs. Doing so would result in an error.
    • Under Previous HOP, the "Get Thread Owner" API can only be called by apps that are either Primary or Secondary receivers. Please note that this behavior is different under New HOP because apps automatically have a role and need not be set. So, ensure you set a role for your app for a Previous HOP page if you would like to use the Get Thread Owner API.
    • Do not assume that any of the New HOP restrictions are in effect.
    • There is no idle mode.
    • There is no exclusivity, any app can send a message to a thread and none of the changes mentioned in the breaking changes section above are applicable.

For pages on New HOP:

  • Your app must:
    • Handle all New HOP events correctly.
    • Consider all new HOP restrictions: exclusivity, idle mode and other changes mentioned in the breaking changes section above.
  • Your app can:
    • Call New HOP APIs to offer greater functionality

After the cutoff date there would be no more Previous HOP support and the code blocks that you have maintained for Previous HOP can be removed.

Use Cases

Use case #1: A business wants to use an automated experience for simple FAQs but wants to transfer the customer to a live support agent for complex inquiries. In this case the automated experience and live agent experiences are powered by 2 different apps.

  • Setup the automation app as the primary app via Page Settings (Page settings > Messenger Platform > Connected Apps).
  • Subscribe both apps to standby and messaging_handover webhook events to ensure thread events (pass, request, taken) events are handled properly.
  • By default, all thread ownership will go to the automation app. Live agent app should not interfere with the automation flow unless thread control is passed. If the live agent needs to interject the conversation, leverage Request Thread Control API to notify the automation app that they want to interject the thread. This will ensure that there’s no duplicate replies from both automation and live agent app.
  • Automation app should pass the thread control to live agent app whenever the automation app can’t handle customer requests.
  • Once live agent app has completed the conversation, pass back thread control to the automation app.
  • If the live agent app needs more time to handle user enquires, leverage the Extend Thread Control API to extend thread ownership.
  • Optionally, you can leverage the Pass Metadata API to pass any metadata between apps without changing thread ownership.

Use case #2: A business wants to run a marketing campaign and wants to use an automated experience to qualify leads or provide product recommendations based on product quiz. After the lead qualification, the business would like to use Facebook Page Inbox to follow up with the prospect.

  • Subscribe the automation app to standby and messaging_handover webhook events to ensure thread events (pass, request, taken) events are handled properly.
  • Once the automated app has completed the lead qualification phase, pass thread control to Facebook Page Inbox using Pass Thread Control API. Set the target_app_id to 263902037430900 (app id of Facebook Page Inbox).
  • Once the conversation is done in Facebook Page Inbox, mark the thread as ‘Done’. This will release the thread control to primary app (if any) or set as idle mode.

Use case #3: A business wants to run a marketing campaign and send prospects to a specific Messenger experience but do not want the customer support agents on the business page to be distracted by messages coming from the campaign.

  • Setup the ads via ads manager by following the Handover Protocol for ads that click to Messenger guide.
  • Subscribe both apps to standby and messaging_handover webhook events to ensure thread events (pass, request, taken) events are handled properly.
  • Ensure that the live agent app respect the thread ownership logic. Live agent app inbox should hide/group threads that are not currently being owned separately to ensure that live agents are not responding to the threads.
  • Ensure correct implementation of webhooks received from standby channel. Treat them separately and don’t assume thread ownership unless explicitly passed to the app or the app has requested thread ownership via Request Thread Control API.
  • When an escalation to a live agent is needed, the automation app can use pass thread control to the live agent app.

Best Practices

  1. We recommend automated experiences to be set as the primary receiver app and any live agent app to be the non-primary app. It’s recommended that the live agent app listens to the standby events and not take action unless needed.
  2. Always use the Get Thread Control API to check if you are in control of the thread or not, then call the other APIs based on the scenario. Do not interject or interrupt if you do not have control.
  3. Please ensure that you do not try to send messages to the thread when another app is in control of the conversation. If you are a Primary app please use the take thread control API only if you see the need to. In non-urgent cases or if you are a non-primary app please request thread control.
  4. Ensure that you honor a request thread control event from any other app in all cases possible and pass thread control to the requesting app. If for any reason you are unable to pass thread control immediately, use the Pass Metadata API to send additional context to the requesting app and maintain a queue to pass thread control when you are done.
  5. If you are done with the conversation, please pass thread control to a previously requesting app still in queue or release thread control to idle, so that any other app can pick up the thread. Not doing so, would result in the thread automatically releasing from your app and going to idle mode after 24 hours. Code this scenario and its associated state changes accordingly.
  6. If you notice the thread to be idle by calling the Get Thread Control API, use Request Thread Control to take control of the thread so that you can exclusively message the user without disruptions and release once done.

Case Studies

  1. Thalys and developer partner Mindsay launched a hybrid customer support experience that uses both automation and their team of in-house customer service experts to improve operational efficiency by 68%.
  2. Klarmobil and Khoros used Messenger's Handover Protocol to seamlessly transfer control between its automation app and the live agent app to increase first contact resolution by 35%.
  3. Decathlon UK and developer partner Heyday built a Messenger-powered digital assistant that would offer an always-on method for solving customer’s simple queries with an option to reach a live agent resulting (supported by Handover Protocol) in 25% decrease in support costs & a 10 pts increase in customer satisfaction.

Troubleshooting

Disabling/Uninstalling HOP

If Handover Protocol is not longer needed a Page Admin needs to disable this configuration from the Page.

Go to Advanced Messaging Setting. For regular Pages it will be located on Settings > Advance Messaging Tab. For Pages under the New Pages Experience it will be under Settings > New Pages Experience > Advanced Messaging.

In App settings section under Handover protocol click Configure to configure primary and secondary receivers settings

De-Select apps for both the Primary and Secondary Receiver. This will disable Handover Protocol for the Page.

All Messages are going to the 'Done' folder

When HOP is enabled, threads are owned by apps. Page inbox is just another app in the roster. If Page Inbox does not own the thread the conversation will appear in the Done folder. When Page inbox is set as secondary receiver all new threads will go by default to the Done folder as they are not owned by the Page Inbox.

If this behavior is not desired, consider either Disabling HOP or setting the Page Inbox as the Primary Receive so that by default all new threads are first owned by the Page Inbox.

Disable HOP before Uninstalling the last App from your Page

Handover Protocol Settings is that they are not available if no apps are installed on the Page. This is by design, without apps, coordination between apps is not relevant.

A known issue for Pages with Handover Enabled is that if you remove all the connected apps the HOP setting will be kept even after the last app is removed. This can cause the Messages are going to the 'Done' folder without a way to remove this settings.

To fix this. Install a messaging app to have at least one app installed. Here is a list of apps by partners, many with a free tier. This will allow the HOP settings to be re-enabled. You can now Disable HOP before removing the last app from your Page.

FAQ

Q: Are there any changes to app setup to enable Handover Protocol?

A: Yes, brands will no longer need to assign primary or secondary roles to apps to enable handover protocol. Optionally, Brands can choose to assign a primary/secondary role to an app but this is no longer a requirement to enable handover protocol. We want to keep the app setup simple and minimize the interdependency on apps as much as possible.

Q: Is there a recommendation on which app should be assigned a primary role?

A: We recommend brands assign apps that have an automated experience to be the primary. These apps can field some of the initial inquiries from users before transferring them to a human agent.

Q: Can brands assign an app to each entry point?

A: Currently, we are allowing brands to assign an app to Ads that Click to Messenger. We will provide updates as we introduce the ability to assign an app to other entry points.

Q: Which apps can take control of the thread during idle mode?

A: If a primary app role is set, the primary app will receive control of the thread by default. When a user messages a page in ** idle mode, all the apps connected to the page will receive the events on the messaging channel. However, if primary app is set events will be received on the messaging channel by the primary app and on the standby channel for other apps.

However, if there is no primary app set, other apps can take thread control by calling the “Take Thread Control” API. The app which calls the “Take Thread Control“ API first will get the control of the thread.

Q: Will Sponsored messages be sent when an app is in control of the thread?

A: Yes, sponsored messages will be sent even if another app is in control of the thread.

Q: Is there any impact to messages sent with message tags?

A: Yes, the messages sent with message tags (with the exception of human agent tag) won’t be delivered if another app is in control of the thread. If the message is tagged with the human agent tag, then the app sending that message will receive control of the thread. Developers will be able to use the thread owner API to check when a thread goes into idle mode. We will also have a dedicated error for send api/menu update failures due to exclusive mode.

Q: If a page has multiple apps connected to it and none of the apps have been assigned a primary role, will all the apps receive the webhook events?

A: Yes, all apps connected to the page will receive the webhook events. Also, if the thread is owned by a particular app that app will get events in the messaging channel, and all others will get the events in the standby channel.

Q: A page is connected to a live agent app that uses the human agent tag to send messages outside the 24 hour messaging window. Will those messages be delivered to the user?*

A: Yes, messages that are sent using the human agent tag will be delivered to the user even if the thread is controlled by another app. The live agent app will gain control of the thread when the message is tagged with the human agent message tag.

Q: One of my brands is running a Click to Messenger ad and wants to send the traffic to the marketing app. But there is already a live agent app connected to the page. Does the brand need to make any changes to other apps connected to the page?

A: We want to make it easy for brands to run click to Messenger ads to a specific app. Brands will be able to assign an app specific to a CTM ad. The brand can ask the live agent app to subscribe to “Stand by” channel if it wishes to get context on the conversations the marketing app is having with the user. The live agent app can also choose to turn off “Stand by” channel.

Unlike the previous version of Handover Protocol where a Page needs to assign the marketing app as secondary for CTM HOP to work, Pages no longer need to assign a role to the app with the new improvements to Handover Protocol. Pages can just connect the app developed for the Click to Messenger campaign and the app will be automatically assigned a secondary role.

Q: Brands often send out NPS or CSAT surveys after an agent interaction. Will those surveys be delivered when another app is in control of the thread?

A: NPS and CSAT surveys can be sent once the thread enters idle mode. Please refer to Customer Feedback Template documentation for more details.

Q: Can a live agent app take over control of the thread from an automated experience?

A: Yes, if the live agent app is set as the primary app on the page. If not, the live agent app can request control from the automation app and have the automation app pass control to the live agent app. The live agent app can also take control of the thread in idle mode.

Q: Can an app extend ownership of the thread?* *If so, is there a limit to the # of extensions that the app can request?

A: Yes, an app can request for extension of the thread ownership. There is no limit to the # of extensions an app can request.

Q: Is there a way for an app to see all the other apps connected to the page?

A: Yes, only primary app on the page can see all the other apps connected to the page. To programmatically retrieve the list of apps for your Page, send a GET request to the Messenger Platform with the page token of the Primary Receiver app.

Q: A user clicks a post back CTA (ex: Button) owned by app A, when the user is waiting for a live agent app (App B) to respond (i.e. App B is in control). Will app A get control of the thread?

A: Yes, we will honor user actions. As soon as the user clicks on a post back CTA owned by app A, the thread ownership will go back to app A.

Q: A brand uses page inbox to respond to customer inquiries manually and uses a 3rd party app for automated answers. Can the brand assign a secondary role to Page inbox?

A: Page Inbox can’t be assigned as a primary app on the page. It will always have a secondary role.

Q: A brand uses Facebook Page Inbox to respond to customer inquiries manually and uses a 3rd party app for automated answers. One of the agents tries to respond to a customer inquiry via Facebook Page Inbox while the user is having a conversation with the automated app. Will page inbox get thread control? Will the agent be able to send the message?

A: Yes, agent using Facebook Page Inbox will be able to send a message to the user when the user is engaged with the automation app. After the message is sent the thread control is passed to the Facebook Page Inbox if the admin responds to the user inquiry from the Main folder. If an admin responds to the user inquiry from the Done folder the control is _*not passed* _to Page Inbox.

Q: How does Facebook Page Inbox & a third party app interaction work given the improvements to Handover Protocol?

A:

  1. If a page is connected to a third-party app and a user has a conversation with a third-party app, all the conversations will appear in the “Done” folder within Facebook Page Inbox.
  2. An admin using Facebook Page Inbox can interrupt the third-party app conversation if needed. Ideally the third-party app is setup in a way to allow seamless transfer of thread control to Facebook Page Inbox if the user needs help from a human agent.
  3. If a third-party app is unable to handle a question it should pass the control to the Facebook Page Inbox. At this time, the thread will move to the Main folder, which will show the agent that they need to respond.
  4. If an admin responds to a user from the Done folder the control is not passed to Facebook Page Inbox.
  5. If an admin moves the conversation to Main folder the thread control is passed to Facebook Page Inbox.

Q: How are apps notified when a thread moves to Idle mode?

A: Apps won’t be notified when a thread moves to Idle mode. We recommend businesses check if another app is in control of the thread by calling the Get Thread Owner API. The API will return null if the thread is in Idle mode.

Q: My client has icebreakers setup on the page and wants to run Ads that Click to Messenger. Will the people clicking on the ad see the Icebreakers or the Welcome message set on the ad?

A: Welcome message set on the ad will take precedence over Icebreakers set on the page. People will see the welcome message set on the ad once they click the ad.

Q: My client has Icebreakers setup on the page and wants to run Traffic Objective ads with destination URL as the M.me link? When a person clicks on the ad, the Icebreakers are surfaced instead of the Welcome message. Why is that the case?

A: Icebreakers are set at the page level. When a M.me link is used, people are sent to the organic experience on the Facebook Page. For businesses who want their users to enter the ad experience vs. the organic experience, we recommend they turn off the Icebreakers on the Facebook Page.