On June 8th, 2021 with v11.0 we added the mid field to the messaging_postbacks webhook event to allow apps to get the Message ID.

The Messenger Platform sends events to your webhook to notify you when a variety of interactions or events happen, including when a person sends a message. Webhook events are sent by the Messenger Platform as POST requests to your webhook.


App needs to be subscribed to Page and pages_messaging permission needs to be granted from the Page to the app for messaging webhooks to be sent.

Setting Up Your Webhook

Setting up a callback URL for webhook events requires verification that you control or own the domain that hosts your application.

  1. Developer provides the webhook URL along with a developer generated verify token via the app dashboard.
  2. The Messenger Platform will try to verify your webhook by sending a GET request to the callback URL with the parameters listed below.
  3. The callback URL responds with the value of the hub.challenge sent. The URL should validate that the hub.verify_token matches with the token that was entered in the app dashboard.

Parameters provided in the GET request

Parameter Description


Set to subscribe


The custom verify token that the developer provided


Generated by the Messenger Platform. Contains the expected response.

For sample code on how to verify the callback URL, see Webhook Setup. Also see Validating Webhook Events to verify that callback events come from a trusted source.

Development Mode

Apps in development mode will receive these Webhook Events but limited to actions taken by users who have a role on the app.

Webhook Events

The available webhook events are listed below. All webhook events are optional, so select those that are most relevant for the experience you are trying to create.

Webhook Event Description


Subscribes to Message Received events


Subscribes to Account Linking events


Subscribes to Message Delivered events


Subscribes to Message Echo events


Subscribes to Instant Game events


Subscribes to Handover Protocol events


Subscribes to Plugin Opt-in events


Subscribes to Policy Enforcement events


Subscribes to Postback Received events


Subscribes to Message Reaction events


Subscribes to Message Read events


Subscribes to Referral events


Subscribes to Handover Protocol Standby Channel events

Event Format

All webhook events have a common structure that includes information you will need to process and respond to the event, including the PSID of the sender and recipient of the event. In addition to the properties shown below, each event also has its own event-specific properties.

Note that entry is an array and may contain multiple objects, so ensure your code iterates over it to process all events. For a complete description of event properties, see Webhooks Reference.



Required 200 OK Response

When you receive a webhook event, you must always return a 200 HTTP response. Avoid procesing the webhook in sync and instead return HTTP 200 response early. The Messenger Platform will resend the webhooks when it receives an error HTTP response or timeouts, until an HTTP 200 response is received. Delays in responding might trigger retries. Failing to return a 200 OK may cause your webhook to be unsubscribed by the Messenger Platform.

A delivery receipt will automatically be sent to the user after your webhook has acknowledged the message. You can also use Sender Actions to notify that the message has been seen.

Changing Your Webhook

To edit your webhook URL or verify token, do the following:

  1. In your app dashboard, click the "Add Product" button.
  2. Add the "Webhooks" product. That will present you with an interface to edit your webhook.
  3. In the Webhooks settings, click the 'Edit Subscriptions' button.
  4. Update your webhook details.
  5. Click the 'Verify and Save' button. The Messenger Platform will verify your webhook and save the new details on success.

Note any time you change your webhook details, the Messenger Platform will perform a verification of your webhook.

Webhook Performance Requirements

Your webhook should meet the following minimum performance standards:

  • Early respond to all webhook events with a HTTP 200 response
  • Respond to all webhook events within 5 seconds or less

If your webhook fails to meet either of the above requirements for more than 15 minutes a 'Webhooks Failing' alert will appear in the 'Alerts' page of your app settings.

If your webhook continues to fail for 1 hour, you will receive a 'Webhooks Disabled' alert, and your Facebook app will be unsubscribed from receiving webhook events for the Page.

Once you have fixed the issues with your webhook, you must set up your webhook again.

Validating Webhook Events

It is strongly recommended to implement signature verification of webhooks on your server for production apps. This feature allows Server for Callback URL to verify the webhook sender knows the App Secret.

Webhooks sent will contain an HTTP Header X-Hub-Signature with the SHA1 signature of the post payload. Server can use this information to ignore webhooks that don't contain the expected signature and ignore attacks based on injecting webhooks.

The signature is calculated using the keyed-hash message authentication code (HMAC) where the key is the app secret. The signature is then prefixed with sha1=. Your callback endpoint can verify this signature to validate the integrity and App origin of the payload.

Please note that the calculation is made on the raw escaped Unicode version of the payload, with lower case hex digits. For example, the string äöå will be escaped to \u00e4\u00f6\u00e5. The calculation also escapes / to \/, < to \u003C, % to \u0025 and @ to \u0040. If signature is calculated against the decoded bytes, you will end up with a different signature.

Code Example

$appsecret = 'YOUR APP SECRET';
$raw_post_data = file_get_contents('php://input');
$header_signature = $headers['X-Hub-Signature'];

// Signature matching
$expected_signature = hash_hmac('sha1', $raw_post_data, $appsecret);

$signature = '';
    strlen($header_signature) == 45 &&
    substr($header_signature, 0, 5) == 'sha1='
  ) {
  $signature = substr($header_signature, 5);
if (hash_equals($signature, $expected_signature)) {

Learn More