WhatsApp channel message support

The WhatsApp channel of the Conversation API supports a wide variety of message types, including the the rich template, media, and location message types supported by the WhatsApp API.

Sending Messages

Prior to sending messages on the WhatsApp channel using the Conversation API generic message format, note the following:

  • Sending a generic message format requires a started customer care session . Sending messages outside of a customer care session requires a template .
  • All business initiated conversations on the WhatsApp channel should start with an “Opt-In” by the user. This can be collected through any third party channel. For example in an SMS message, a web form, email etc. Businesses must also provide a method by which customers may opt-out of receiving future messages from your organization.
Note:

Starting June 30th, 2022, the Conversation API will not check whether recipients have opted in before sending messages. It is the user's responsibility to ensure that the recipient has opted in before sending.

The following table details the mapping between the Conversation API generic message format and how WhatsApp renders the messages on mobile devices:

Message Type Natively Supported? Special Instructions
Text Message Yes, this type of message is natively supported. For example:
Text Message

The code to send a text message for this channel doesn't differ from the generic message and can be viewed here.

Media Message Yes, this type of message is natively supported for the following media types (the WhatsApp channel will automatically detect what type of WhatsApp media message to use):
  • Image: image/.jpeg, image/.png
  • Video: video/.mp4, video/.3gpp (Only H.264 video codec and AAC audio codec is supported with a single audio stream)
  • Audio: audio/.aac, audio/.mp4, audio/.amr, audio/.mpeg, audio/.ogg + codecs=opus (base audio/.ogg not supported)
  • Document: any valid document MIME type
  • Sticker: image/.webp
. For example:
Media Message

The code to send a media message for this channel doesn't differ from the generic message and can be viewed here.

Choice Message This type of message is natively supported (through the use of quick reply buttons) if:
  • The choice message contains only text.
  • The message contains no more than three choices.
  • The title of the choice message is set and is no longer than 1024 characters.
  • Each choice is no more than 20 characters and doesn't contain markdown.
  • All choices are unique.
  • Postback data is no more than 229 characters long.
For example:
Choice Message
If these conditions are not met, the message is converted into plain text.

The code to send a choice message for this channel doesn't differ from the generic message and can be viewed here.

Card Message This type of message is natively supported if you only include text choices in your card message. Note that:
  • Image or video media will be displayed as rich content.
  • Audio or sticker media will be included as plaintext link on the card due to a limitation of the WhatsApp Business API.
  • Document media can be displayed as rich content when all the choices contain only text. Otherwise it will be a plaintext link in the card.
For example:
Card Message

The code to send a card message for this channel doesn't differ from the generic message and can be viewed here.

Carousel Message No, this type of message will be converted into plaintext. For example:
Carousel Message

The code to send a carousel message for this channel doesn't differ from the generic message and can be viewed here.

Location Message Yes, this type of message is natively supported. For example:
Location Message

The code to send a location message for this channel doesn't differ from the generic message and can be viewed here.

Choice List Message Yes, this type of message is natively supported. For example:
List Message
The detailed view of the message is displayed below:
List Message Details

The code to send a list message for this channel doesn't differ from the generic message and can be viewed here.

Product List Message (Single Product) Yes, this type of message is natively supported. For example:
Single Product Message
The detailed view of the message is displayed below:
Single Product Details

The code to send a list message for this channel doesn't differ from the generic message and can be viewed here.

Product List Message (Multi-Product) Yes, this type of message is natively supported. For example:
Product List Message
The detailed view of the message is displayed below:
Product List Message Details

The code to send a list message for this channel doesn't differ from the generic message and can be viewed here.

Explicit Channel Messages

Conversation API provides a way to use channel specific message formats. If you know the underlying channel's API (in this case, the WhatsApp Business API), and you want to use a feature that's not supported by Conversation API message types, you can pass the JSON format of the WhatsApp Business API to Conversation API too. When you want to use a channel specific format, you need to pass this JSON as an escaped string to Conversation API.

For example, consider the Interactive List message. While we can send this message as a choice list message, it can also be sent using the WhatsApp Business API. This example message is sent using a Conversation API POST to the messages:send endpoint:

Copy
Copied
{
  "message": {
    "explicit_channel_message": {
      "WHATSAPP": "{\r\n  \"to\": \"{{to}}\",\r\n  \"type\": \"interactive\",\r\n  \"recipient_type\": \"INDIVIDUAL\",\r\n  \"interactive\": {\r\n    \"type\": \"list\",\r\n    \"body\": {\r\n      \"text\": \"This is the card title\"\r\n    },\r\n    \"footer\": {\r\n      \"text\": \"This is the card description\"\r\n    },\r\n    \"action\": {\r\n      \"button\": \"Menu\",\r\n      \"sections\": [\r\n        {\r\n          \"rows\": [\r\n            {\r\n              \"id\": \"firstreply\",\r\n              \"title\": \"First Reply\"\r\n            },\r\n            {\r\n              \"id\": \"secondreply\",\r\n              \"title\": \"Second Reply\"\r\n            },\r\n            {\r\n              \"id\": \"thirdreply\",\r\n              \"title\": \"Third Reply\"\r\n            }\r\n          ]\r\n        }\r\n      ]\r\n    }\r\n  }\r\n}"
    }
  }
}

The rendered message:

Explicit Channel Message

Receiving Delivery Receipts

Messages sent on WhatsApp channel can have three statuses: DELIVERED, READ, or FAILED. If the status is FAILED, a reason will be included that provides more information about the failure.

Note:

Not all messages that are successfully delivered have both DELIVERED and READ statuses. Only a READ receipt is sent if the contact's WhatsApp app and conversation are active when the message is received.

Below is an example of a Conversation API POST to the MESSAGE_DELIVERY webhook with a READ receipt; a FAILED or DELIVERED receipt would have a different status, and a FAILED status would have a reason.

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "accepted_time": "2020-06-22T11:05:53.910Z",
  "message_delivery_report": {
    "message_id": "01EBDV9EFP66ZA0GQJ9MCX1V9H",
    "conversation_id": "01EB199XQ2CBY50K6WZD9S1A22",
    "status": "READ",
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "+46702471483",
      "app_id": ""
    },
    "contact_id": "01EB197NDA4W7V15NPRCVV0S79",
    "metadata": "",
    "processing_mode": "CONVERSATION"
  },
  "message_metadata": "{\"pricing_category\":\"user_initiated\",\"whatsapp_conversation_id\":\"a49709b572981c281648d7d23e95412c\"}"
}

Receiving Pricing Model Information

Starting February 1st, 2022, the WhatsApp pricing model is conversation-based instead of notification-based. This means that customers are charged per conversation. A conversation starts with the first delivered message and includes all messages delivered in a 24-hour session. The price for the conversation depends on the pricing category of the conversation:

  • User-initiated , which defines conversations initiated in response to a user message.
  • Business-initiated , which defines conversations initiated from a business outside the 24-hour customer service window. Note that starting a conversation outside the 24-hour customer service window requires a template message.
  • Referral conversion , which defines conversations that do not incur a charge. These conversations are typically initiated when an end-user messages the business by clicking a call-to-action button on an ad. For example, a user clicking on a Facebook ad may trigger a referral conversion conversation.
Note

For more information regarding this WhatsApp update, see their article on Conversation-Based Pricing.

To inform the Conversation API user about the pricing of their WhatsApp conversation, delivery receipt callbacks with the DELIVERED status will contain additional message_metadata with info about:

  • pricing_category , which is the pricing category for the conversation.
  • whatsapp_conversation_id , which is the WhatsApp conversation id (messages with the same id belong to the same conversation).

For example:

Copy
Copied
{
    "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
    "accepted_time": "2020-06-22T11:05:53.910Z",
    "message_delivery_report": {
        "message_id": "01EBDV9EFP66ZA0GQJ9MCX1V9H",
        "conversation_id": "01EB199XQ2CBY50K6WZD9S1A22",
        "status": "READ",
        "channel_identity": {
            "channel": "WHATSAPP",
            "identity": "+46702471483",
            "app_id": ""
        },
        "contact_id": "01EB197NDA4W7V15NPRCVV0S79",
        "metadata": "",
        "processing_mode": "CONVERSATION"
    },
    "message_metadata": "{\"pricing_category\":\"user_initiated\",\"whatsapp_conversation_id\":\"a36709b572981c281648d7d23d91588z\"}"
}

When the first delivery receipt with a DELIVERED status and a new whatsapp_conversation_id is received, the customer is charged for a new conversation. All messages sent to the same recipient within a 24-hour window are part of that same conversation, and don't incur additional charges.

Receiving Messages

WhatsApp channel supports various kinds of contact messages - text, media, media card, location, and choice response.

Note:

Please note that the media URLs included in the contact messages are valid for 7 days. After that the media is deleted from Conversation API storage.

All of these are delivered by Conversation API with a POST to the MESSAGE_INBOUND webhook:

Text message response webhook example

Below is an example of a Conversation API POST to the MESSAGE_INBOUND webhook for a text message response:

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "accepted_time": "2020-06-22T10:55:39.534687Z",
  "message": {
    "id": "01EBDTPPG3Q3EH14H7DY8X09MG",
    "direction": "TO_APP",
    "contact_message": {
      "text_message": {
        "text": "Hi from contact"
      }
    },
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "46712312312",
      "app_id": ""
    },
    "conversation_id": "01EB199XQ2CBY50K6WZD9S1A22",
    "contact_id": "01EB197NDA4W7V15NPRCVV0S79",
    "metadata": "",
    "accept_time": "2020-06-22T10:55:39.521500Z"
  }
}

Media message response webhook example

Below is an example of a Conversation API POST to the MESSAGE_INBOUND webhook for a media message response:

Copy
Copied
{
  "app_id": "01EB37HMH1M6SV18ASNS3G135H",
  "accepted_time": "2020-10-01T12:10:55.073703Z",
  "event_time": "2020-10-01T12:10:53.991Z",
  "project_id": "c36f3d3d-1513-4edd-ae42-11995557ff61",
  "message": {
    "id": "01EKJ1534NWK5R02TGWEJN13HA",
    "direction": "TO_APP",
    "contact_message": {
      "media_message": {
        "url": "https://1vxc0v12qhrm1e72gq1mmxkf-wpengine.netdna-ssl.com/wp-content/uploads/2019/05/Sinch-logo-Events.png"
      }
    },
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "46712312312",
      "app_id": ""
    },
    "conversation_id": "01EKJ0KSWXMVDF05MG9TQ20S06",
    "contact_id": "01EKA07N79THJ20WSN6AS30TMW",
    "metadata": "",
    "accept_time": "2020-10-01T12:10:55.060170Z"
  }
}

Media card message response webhook example

Below is an example of a Conversation API POST to the MESSAGE_INBOUND webhook for a media card message response:

Copy
Copied
{
  "app_id": "01EB37HMH1M6SV18ASNS3G135H",
  "accepted_time": "2020-10-01T12:10:55.073703Z",
  "event_time": "2020-10-01T12:10:53.991Z",
  "project_id": "c36f3d3d-1513-4edd-ae42-11995557ff61",
  "message": {
    "id": "01EKJ1534NWK5R02TGWEJN13HA",
    "direction": "TO_APP",
    "contact_message": {
      "media_card_message": {
        "url": "https://1vxc0v12qhrm1e72gq1mmxkf-wpengine.netdna-ssl.com/wp-content/uploads/2019/05/Sinch-logo-Events.png",
        "caption": "caption text"
      }
    },
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "46712312312",
      "app_id": ""
    },
    "conversation_id": "01EKJ0KSWXMVDF05MG9TQ20S06",
    "contact_id": "01EKA07N79THJ20WSN6AS30TMW",
    "metadata": "",
    "accept_time": "2020-10-01T12:10:55.060170Z"
  }
}

Location message response webhook example

Below is an example of a Conversation API POST to the MESSAGE_INBOUND webhook for a location message response:

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "accepted_time": "2020-06-22T10:57:36.074692Z",
  "message": {
    "id": "01EBDTT89ZGTGM0P70W0RK0YR2",
    "direction": "TO_APP",
    "contact_message": {
      "location_message": {
        "title": "ICA Jägaren",
        "coordinates": {
          "latitude": 55.727802,
          "longitude": 13.175061
        },
        "label": ""
      }
    },
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "46712312312",
      "app_id": ""
    },
    "conversation_id": "01EB199XQ2CBY50K6WZD9S1A22",
    "contact_id": "01EB197NDA4W7V15NPRCVV0S79",
    "metadata": "",
    "accept_time": "2020-06-22T10:57:36.060961Z"
  }
}

Choice message response webhook example

Below is an example of a Conversation API POST to the MESSAGE_INBOUND webhook for a choice message response:

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "accepted_time": "2020-06-22T11:00:32.866988Z",
  "message": {
    "id": "01EBDTZMYPHM0G1D0AJFEZ0A4P",
    "direction": "TO_APP",
    "contact_message": {
      "choice_response_message": {
        "message_id": "01EBDTZ9SN8HTW092K56PH1GDS",
        "postback_data": "email_postback"
      }
    },
    "channel_identity": {
      "channel": "WHATSAPP",
      "identity": "46712312312",
      "app_id": ""
    },
    "conversation_id": "01EB199XQ2CBY50K6WZD9S1A22",
    "contact_id": "01EB197NDA4W7V15NPRCVV0S79",
    "metadata": "",
    "accept_time": "2020-06-22T11:00:32.852315Z"
  }
}

Receiving WABA events

In addition to messages, the WhatsApp channel allows you to receive event information about Quality Rating or Daily Limit changes. All of these are delivered by Conversation API with a POST to the CHANNEL_EVENT webhook:

Quality Rating changed webhook example

Below is an example of a Conversation API POST to the CHANNEL_EVENT webhook for a Quality Rating change event:

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "event_time": "2022-07-25T06:23:46Z",
  "project_id": "c36f3d3d-1513-4edd-ae42-11995557ff61",
  "channel_event_notification": {
    "channel_event": {
      "channel": "WHATSAPP",
      "event_type": "WHATS_APP_QUALITY_RATING_CHANGED",
      "additional_data": {
        "quality_rating": "GREEN"
      }
    }
  },
  "message_metadata": ""
}

Daily Limit changed webhook example

Below is an example of a Conversation API POST to the CHANNEL_EVENT webhook for a Daily Limit change event:

Copy
Copied
{
  "app_id": "01E8RCZPK7HFV70FFDWFFK0EXK",
  "event_time": "2022-07-26T08:15:00Z",
  "project_id": "c36f3d3d-1513-4edd-ae42-11995557ff61",
  "channel_event_notification": {
    "channel_event": {
      "channel": "WHATSAPP",
      "event_type": "WHATS_APP_DAILY_LIMIT_CHANGED",
      "additional_data": {
        "daily_limit": "TIER_100K"
      }
    }
  },
  "message_metadata": ""
}
Was this page helpful?