WhatsApp Business Platform

Standby webhooks

Updated: Aug 4, 2026
Copy for LLM
Standby webhooks notify your app about conversation activity on a WhatsApp Business phone number when another sender — such as Meta Business Agent (AI) — is currently handling the conversation.

Overview

When Meta Business Agent is enabled on your WhatsApp Business phone number, it coexists with your app on the same number. At any point in time, one sender is the active handler for a given consumer conversation, and the other is a passive listener.
As the passive listener, your app receives standby webhooks — real-time notifications about what is happening in the conversation without being expected to respond. This allows your app to:
  • Maintain conversation context — Stay informed about the full conversation history so your app can respond intelligently if control is later transferred to it.
  • Monitor messaging activity — Track what Meta Business Agent is saying to WhatsApp users on your behalf.
  • Measure delivery — Observe delivery and read receipts for messages sent by Meta Business Agent.
Standby webhooks are intended for passive listening. However, if your app sends a service message while observing a conversation, it will take over as the active handler. This is a valid way to reclaim ownership of a conversation when needed (for example, to escalate to a human agent).

What is a message echo?

When Meta Business Agent (or another sender on the number) sends an outbound message to a consumer, your app receives an “echo” of that message — a copy of what was sent, so your app stays informed even though it did not initiate the message.

Prerequisites

  • Your app is subscribed to the standby webhook field in the App Dashboard.
  • The business has enabled Meta Business Agent on the phone number and granted your app standby permissions.
  • You have a valid webhook URL configured to receive notifications.

Subscribing to standby webhooks

To receive standby webhooks, subscribe to the standby field in your app’s Webhooks configuration:
  1. Go to your app in the Meta Developer Portal.
  2. Navigate to WhatsApp > Configuration > Webhook fields.
  3. Subscribe to the standby field.

When you receive each webhook type

What happenedWhat your app receivesSub-field
WhatsApp user sends a message (your app is not the active handler)
Standby inbound message
standby.messages
Meta Business Agent sends a message to the WhatsApp user
Standby message echo
standby.message_echoes
A message sent by Meta Business Agent gets delivered or read
Standby status receipt
standby.statuses

What you will NOT receive

You will not receive standby webhooks when:
  • You are the active handler — You receive regular messages webhooks instead (under the messages field).
  • Your own app sends a message — You do not echo yourself.
  • The business hasn’t granted standby permissions — Your app must be configured as a standby listener.
  • You haven’t subscribed to the standby field — Subscription is required in your app’s webhook configuration.

Payload structure

Common envelope

Every standby webhook uses this envelope:
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {}
          },
          "field": "standby"
        }
      ]
    }
  ]
}
The standby object contains one of: messages, message_echoes, or statuses.

Parameters

| Name | Type | Description | |------|------|-------------| | object | string | Always whatsapp_business_account. | | entry | array | Array of entry objects. | | entry[].id | string | Your WhatsApp Business Account ID. | | entry[].changes | array | Array of change objects. | | entry[].changes[].value.messaging_product | string | Always whatsapp. | | entry[].changes[].value.metadata.display_phone_number | string | The business phone number in international format. | | entry[].changes[].value.metadata.phone_number_id | string | ID of the business phone number. | | entry[].changes[].value.standby | object | The standby payload. Contains one of: messages, message_echoes, or statuses. | | entry[].changes[].field | string | Always standby for standby webhooks. |

Standby inbound message

Dispatched when a WhatsApp user sends a message and your app is not the active handler (for example, Meta Business Agent is handling the conversation).

Example payload

{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {
              "contacts": [
                {
                  "profile": {
                    "name": "Test User"
                  },
                  "wa_id": "<WA_ID>"
                }
              ],
              "messages": [
                {
                  "from": "<WA_ID>",
                  "id": "<MESSAGE_ID>",
                  "timestamp": "<TIMESTAMP>",
                  "text": {
                    "body": "Test standby message"
                  },
                  "type": "text"
                }
              ]
            }
          },
          "field": "standby"
        }
      ]
    }
  ]
}

Parameters

NameTypeDescription
standby.contacts
array
Array of contact objects describing the message sender.
standby.contacts[].profile.name
string
The WhatsApp user’s profile name.
standby.contacts[].wa_id
string
The WhatsApp user’s WhatsApp ID (phone number).
standby.messages
array
Array of message objects.
standby.messages[].from
string
Sender’s WhatsApp ID.
standby.messages[].id
string
Unique message identifier (wamid.*).
standby.messages[].timestamp
string
Unix epoch timestamp in seconds.
standby.messages[].type
string
Message type — for example, text, image, document, audio, video, location, contacts, interactive, button, reaction.
standby.messages[].text.body
string
Text content (present when type is text).
All message types supported by WhatsApp (such as image, document, audio, video, location, contacts, interactive, and reaction) are delivered in standby using the same schema as standard incoming message webhooks. The example above shows a text message; other types include their respective content objects.

Standby message echo

Dispatched when Meta Business Agent (or another sender on the number) sends a message to the consumer. The echo contains the send-time parameters exactly as passed to the Send Message API — not the rendered content.

Text message echo

A plain text message sent by Meta Business Agent to the WhatsApp user:
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {
              "message_echoes": [
                {
                  "id": "<MESSAGE_ID>",
                  "timestamp": "<TIMESTAMP>",
                  "message": {
                    "messaging_product": "whatsapp",
                    "to": "<WHATSAPP_USER_PHONE_NUMBER>",
                    "recipient_type": "individual",
                    "type": "text",
                    "text": {
                      "body": "Hello! Your order #12345 has shipped.",
                      "preview_url": true
                    },
                    "context": {
                      "message_id": "<PREVIOUS_MESSAGE_ID>"
                    }
                  }
                }
              ]
            }
          },
          "field": "standby"
        }
      ]
    }
  ]
}

Template message echo

For template messages, the echo contains two template-related objects:
  • message.template — The send-time parameters (template name, language, component variable values) as passed to the Send Message API. This tells you what values were substituted.
  • template (sibling of message, inside each echo object) — The full unhydrated template definition, matching the format described in Templates overview. This tells you the template structure with placeholder markers (for example, 1), not the rendered text.
Use the sibling template object to understand the template layout, and message.template to see which parameter values were filled in at send time.
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {
              "message_echoes": [
                {
                  "id": "<MESSAGE_ID>",
                  "timestamp": "<TIMESTAMP>",
                  "message": {
                    "messaging_product": "whatsapp",
                    "to": "<WHATSAPP_USER_PHONE_NUMBER>",
                    "recipient_type": "individual",
                    "type": "template",
                    "template": {
                      "name": "summer_sale_2026",
                      "language": { "code": "en_US" },
                      "components": [
                        {
                          "type": "header",
                          "parameters": [
                            { "type": "image", "image": { "id": "<MEDIA_ID>" } }
                          ]
                        },
                        {
                          "type": "body",
                          "parameters": [
                            { "type": "text", "text": "Maria" },
                            { "type": "text", "text": "25%" }
                          ]
                        },
                        {
                          "type": "button",
                          "sub_type": "url",
                          "index": 0,
                          "parameters": [
                            { "type": "text", "text": "summer2026" }
                          ]
                        }
                      ]
                    }
                  },
                  "template": {
                    "name": "summer_sale_2026",
                    "language": "en_US",
                    "category": "MARKETING",
                    "components": [
                      { "type": "HEADER", "format": "IMAGE" },
                      { "type": "BODY", "text": "Hi 1, enjoy 2 off!" },
                      { "type": "FOOTER", "text": "Limited time" },
                      {
                        "type": "BUTTONS",
                        "buttons": [
                          { "type": "URL", "text": "Shop Now", "url": "https://example.com/1" }
                        ]
                      }
                    ],
                    "status": "APPROVED"
                  }
                }
              ]
            }
          },
          "field": "standby"
        }
      ]
    }
  ]
}

Interactive flow message echo

A flow-type interactive message sent by Meta Business Agent:
{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {
              "message_echoes": [
                {
                  "id": "<MESSAGE_ID>",
                  "timestamp": "<TIMESTAMP>",
                  "message": {
                    "messaging_product": "whatsapp",
                    "to": "<WHATSAPP_USER_PHONE_NUMBER>",
                    "recipient_type": "individual",
                    "type": "interactive",
                    "interactive": {
                      "type": "flow",
                      "header": {
                        "type": "text",
                        "text": "Book Appointment"
                      },
                      "body": {
                        "text": "Schedule your visit with us."
                      },
                      "footer": {
                        "text": "Tap below to continue"
                      },
                      "action": {
                        "name": "flow",
                        "parameters": {
                          "flow_id": "<FLOW_ID>",
                          "flow_cta": "Book Now",
                          "flow_action": "navigate",
                          "flow_action_payload": {
                            "screen": "APPOINTMENT_SCREEN"
                          }
                        }
                      }
                    }
                  },
                  "flow": {
                    "id": "<FLOW_ID>",
                    "name": "Appointment Booking",
                    "status": "PUBLISHED",
                    "categories": ["APPOINTMENT_BOOKING"]
                  }
                }
              ]
            }
          },
          "field": "standby"
        }
      ]
    }
  ]
}

Parameters

NameTypeDescription
standby.message_echoes
array
Array of echo objects.
standby.message_echoes[].id
string
Unique message ID (wamid.*) assigned at send time.
standby.message_echoes[].timestamp
string
Unix epoch in seconds when the message was sent.
standby.message_echoes[].message
object
The exact request body as passed to POST /{phone-number-id}/messages. Contains all send-time parameters.
standby.message_echoes[].template
object
(Optional) Present only for template messages. The full unhydrated template definition. See Templates overview.
standby.message_echoes[].flow
object
(Optional) Present only for flow messages. The full flow definition as returned by GET /{flow-id}.
For template messages, message.template carries only the send-time parameters (variable values) — see Cloud API — Send message templates. The sibling template object contains the full template definition format as described in Templates overview.

Standby status receipt

Dispatched when there are delivery status updates (sent, delivered, read) for messages sent by Meta Business Agent.

Example payload

{
  "object": "whatsapp_business_account",
  "entry": [
    {
      "id": "<WHATSAPP_BUSINESS_ACCOUNT_ID>",
      "changes": [
        {
          "value": {
            "messaging_product": "whatsapp",
            "metadata": {
              "display_phone_number": "<BUSINESS_PHONE_NUMBER>",
              "phone_number_id": "<PHONE_NUMBER_ID>"
            },
            "standby": {
              "statuses": [
                {
                  "id": "<MESSAGE_ID>",
                  "status": "delivered",
                  "timestamp": "<TIMESTAMP>",
                  "recipient_id": "<RECIPIENT_WA_ID>",
                  "conversation": {
                    "id": "<CONVERSATION_ID>",
                    "origin": {
                      "type": "utility"
                    }
                  },
                  "pricing": {
                    "billable": true,
                    "pricing_model": "PMP",
                    "category": "utility",
                    "type": "regular"
                  }
                }
              ]
            }
          },
          "field": "standby"
        }
      ]
    }
  ]
}

Parameters

NameTypeDescription
standby.statuses
array
Array of status objects.
standby.statuses[].id
string
The message ID this status refers to.
standby.statuses[].status
string
Delivery status: sent, delivered, or read.
standby.statuses[].timestamp
string
Unix epoch in seconds of the status event.
standby.statuses[].recipient_id
string
WhatsApp ID of the message recipient.
standby.statuses[].conversation.id
string
Conversation ID.
standby.statuses[].conversation.origin.type
string
Conversation origin: utility, marketing, authentication, service, or referral_conversion.
standby.statuses[].pricing.billable
boolean
Whether this message is billable.
standby.statuses[].pricing.pricing_model
string
Pricing model (for example, PMP).
standby.statuses[].pricing.category
string
Pricing category.
standby.statuses[].pricing.type
string
Pricing type (for example, regular).

Best practices

  • Use standby for context, not for responding — Standby webhooks are designed for passive listening. If your app needs to take over the conversation, it can do so by sending a service message, which will make it the active handler.
  • Store context from standby events so your app can provide continuity when it becomes the active handler.
  • Handle duplicates — Use the message id field to deduplicate events in case of redelivery.
  • Monitor delivery — Use status receipts to track delivery and read rates for messages sent by Meta Business Agent.

See also