This document describes how to get messaging, conversation, and template analytics, such as the number of messages sent from a business phone number, the number of conversations and their costs for a WhatsApp Business Account (WABA), or the number of times a given template has been read.
Only metrics for business phone numbers and templates associated with your WABA at the time of the request will be included in responses.
Use the WhatsApp Business Account endpoint to get analytics.
GET /<WHATSAPP_BUSINESS_ACCOUNT_ID> ?fields=<FIELDS>.<FILTERING_PARAMETER>
Placeholder | Description | Example Value |
---|---|---|
| Required. Metric. Value can be one of: |
|
| Required. Metric filtering parameter. Append additional filtering parameters using dots. For possible values, see: |
|
The analytics
field provides the number and type of messages sent and delivered by the phone numbers associated with a specific WABA — for conversation metrics, see Conversation Analytics. When calling /{whatsapp-business-account-ID}?fields=analytics.{filtering-parameters}
, you can attach the following parameters.
Name | Description (Click the arrow in the left column for supported options.) |
---|---|
type: UNIX Timestamp | Required. The start date for the date range you are retrieving analytics for. |
type: UNIX Timestamp | Required. The end date for the date range you are retrieving analytics for. |
type: String | Required. The granularity by which you would like to retrieve the analytics. |
type: Array | Optional. An array of phone numbers for which you would like to retrieve analytics. If not provided, all phone numbers added to your WABA are included. |
type: Array | Optional. The types of messages (notification messages and/or customer support messages) for which you want to retrieve notifications. Provide an array and include |
type: Array | Optional. The countries for which you would like to retrieve analytics. Provide an array with 2 letter country codes for the countries you would like to include. If not provided, analytics will be returned for all countries you have communicated with. |
Scenario: You need to get the number of messages sent and delivered by all phone numbers associated with your WABA.
Suggested Solution: Assemble the URL you want to call and include the following filtering parameters: start
, end
, granularity
. Then, make a GET
request to that URL:
curl -i -X GET \
"https://graph.facebook.com/v21.0
/{whatsapp-business-account-ID}
?fields=analytics
.start(1543543200)
.end(1544148000)
.granularity(DAY)
&access_token={access-token}"
A successful response returns an analytics
object with the data you have requested:
{ "analytics": { "phone_numbers": [ "16505550111", "16505550112", "16505550113" ], "country_codes": [ "US", "BR" ], "granularity": "DAY", "data_points": [ { "start": 1543543200, "end": 1543629600, "sent": 196093, "delivered": 179715 }, { "start": 1543629600, "end": 1543716000, "sent": 147649, "delivered": 139032 }, { "start": 1543716000, "end": 1543802400, "sent": 61988, "delivered": 58830 }, { "start": 1543802400, "end": 1543888800, "sent": 132465, "delivered": 124392 } # more data points ] }, "id": "102290129340398" }
The conversation_analytics
field provides cost and conversation information for a specific WABA. When calling /{whatsapp-business-account-ID}?fields=conversation_analytics.{filtering-parameters}
, you can attach the following parameters.
Name | Description (Click the arrow in the left column for supported options.) |
---|---|
type: UNIX Timestamp | Required. The start date for the date range you are retrieving analytics for. |
type: UNIX Timestamp | Required. The end date for the date range you are retrieving analytics for. |
type: String | Required. The granularity by which you would like to retrieve the analytics. |
type: Array | Optional. An array of phone numbers for which you would like to retrieve analytics. If not provided, all phone numbers added to your WABA are included. |
| Optional. List of metrics you would like to receive. If you send an empty list, we return results for all metric types. |
| Optional. List of conversation categories. If you send an empty list, we return results for all conversation categories. |
| Optional. List of conversation types. If you send an empty list, we return results for all conversation types. |
| Optional. List of conversation directions. If you send an empty list, we return results for all conversation directions. |
| Optional. List of breakdowns you would like to apply to your metrics. If you send an empty list, we return results without any breakdowns. |
Analytics data is approximate and may differ from what’s shown on invoices due to small variations in data processing.
Given a time range, you can get conversation and cost information associated with your WABA. If you want, you can filter and break down your results. See the code samples below for examples.
Scenario: Given a month, you want to retrieve all conversation and cost information for all phone numbers associated with a WABA.
Suggested Solution: Assemble the URL you want to call and include the following filtering parameters:
start
: Start of your time range. In this case, the beginning of the month you want metrics for.end
: End of your time range. In this case, the end of the month you want metrics for.granularity
: How granular you want your data points to be. In the example below, we use MONTHLY
, so each datapoint will represent a month’s worth of data.phone_numbers
: Send an empty array and we return information for all phone numbers associated with the WABA.dimensions
: Set it to all available breakdowns: "CONVERSATION_CATEGORY"
, "CONVERSATION_TYPE"
, "COUNTRY"
, and "PHONE"
.In this case, you do not need to specify country_codes
, metric_types
, conversation_types
and conversation_categories
. If you don't send us anything for those fields, we return all available options. Once you set up the URL, make a GET request:
curl -i -X GET
"https://graph.facebook.com/v21.0
/{whatsapp-business-account-id}
?fields=conversation_analytics
.start(1685602800).end(1688194800)
.granularity(MONTHLY)
.phone_numbers([])
.dimensions(["CONVERSATION_CATEGORY","CONVERSATION_TYPE","COUNTRY","PHONE"])
&access_token={access-token}"
A successful response returns a conversation_analytics
object with the data you have requested. In the following example, the WABA contains only one phone number.
{ "conversation_analytics": { "data": [ { "data_points": [ { "start": 1685602800, "end": 1688194800, "conversation": 1558, "phone_number": "15550458206", "country": "US", "conversation_type": "REGULAR", "conversation_direction": "UNKNOWN", "conversation_category": "AUTHENTICATION", "cost": 15.58 }, { "start": 1685602800, "end": 1688194800, "conversation": 2636, "phone_number": "15550458206", "country": "US", "conversation_type": "REGULAR", "conversation_category": "MARKETING", "cost": 26.36 }, { "start": 1685602800, "end": 1688194800, "conversation": 2238, "phone_number": "15550458206", "country": "US", "conversation_type": "REGULAR", "conversation_category": "SERVICE", "cost": 22.38 }, { "start": 1685602800, "end": 1688194800, "conversation": 1782, "phone_number": "15550458206", "country": "US", "conversation_type": "REGULAR", "conversation_category": "UTILITY", "cost": 17.82 }, { "start": 1685602800, "end": 1688194800, "conversation": 1568, "phone_number": "15550458206", "country": "US", "conversation_type": "FREE_TIER", "conversation_category": "AUTHENTICATION", "cost": 15.68 }, { "start": 1685602800, "end": 1688194800, "conversation": 2716, "phone_number": "15550458206", "country": "US", "conversation_type": "FREE_TIER", "conversation_category": "MARKETING", "cost": 27.16 }, { "start": 1685602800, "end": 1688194800, "conversation": 2180, "phone_number": "15550458206", "country": "US", "conversation_type": "FREE_TIER", "conversation_category": "SERVICE", "cost": 21.8 }, { "start": 1685602800, "end": 1688194800, "conversation": 1465, "phone_number": "15550458206", "country": "US", "conversation_type": "FREE_TIER", "conversation_category": "UTILITY", "cost": 14.65 }, { "start": 1685602800, "end": 1688194800, "conversation": 1433, "phone_number": "15550458206", "country": "US", "conversation_type": "FREE_ENTRY_POINT", "conversation_category": "SERVICE", "cost": 14.33 } ] } ] }, "id": "102290129340398", }
Scenario: Given a time range, you want to retrieve all conversation and cost information for a specific phone number associated with a WABA. In the results, you want to use all possible breakdowns. You need each data point to represent half an hour’s worth of data.
Suggested Solution: Assemble the URL you want to call and include the following filtering parameters:
start
: Start of your time range. end
: End of your time range.granularity
: How granular you want your data points to be. In the example below, we use HALF_HOUR
, so each datapoint represents half an hour’s worth of data.phone_numbers
: The phone number you need information for.dimensions
: Set it to all available breakdowns: CONVERSATION_CATEGORY
, CONVERSATION_TYPE
, COUNTRY
, and PHONE
.In this case, you do not need to specify country_codes
, metric_types
, conversation_types
, or conversation_categories
. If you don’t send us anything for those fields, we return all available options. Once you set up the URL, make a GET request:
curl -i -X GET \
"https://graph.facebook.com/v21.0
/{whatsapp-business-account-id}
?fields=conversation_analytics
.start(1685602800)
.end(1685689200)
.granularity(HALF_HOUR)
.phone_numbers(["19195552584"])
.dimensions(["CONVERSATION_CATEGORY","CONVERSATION_TYPE","COUNTRY,PHONE"])
&access_token=your-access-token"
A successful response returns a conversation_analytics
object with the data you have requested:
{ "conversation_analytics": { "data": [ { "data_points": [ { "start": 1685602800, "end": 1685604600, "conversation": 4, "phone_number": "19195552584", "country": "US", "conversation_type": "REGULAR", "conversation_direction": "UNKNOWN", "conversation_category": "SERVICE", "cost": 0.0232 }, { "start": 1685602800, "end": 1685604600, "conversation": 4, "phone_number": "19195552584", "country": "US", "conversation_type": "REGULAR", "conversation_direction": "UNKNOWN", "conversation_category": "MARKETING", "cost": 0.0232 }, # ... more data points ] } ] }, "id": "102290129340398" }
Scenario: Given a time range, you want to retrieve all conversation and cost information for all phone numbers associated with a WABA. In the results, you want to break down by conversation type.
Suggested Solution: Assemble the URL you want to call and include the following filtering parameters:
start
: Start of your time range. end
: End of your time range.granularity
: How granular you want your data points to be. In the example below, we use MONTHLY
, so each datapoint represents half a month’s worth of data.phone_numbers
: Send an empty array and we’ll return information for all phone numbers associated with the WABA.dimensions
: Set it to CONVERSATION_TYPE
.In this case, you do not need to specify country_codes
, metric_types
, conversation_types
, conversation_directions
, or conversation_categories
. If you don't send us anything for those fields, we return all available options. Once you set up the URL, make a GET request:
curl -i -X GET
"https://graph.facebook.com/v21.0
/{whatsapp-buiness-account-id}
?fields=conversation_analytics
.start(1643702400).end(1646121600)
.granularity(MONTHLY)
.phone_numbers([])
.dimensions([CONVERSATION_TYPE])
&access_token={access-token}"
A successful response returns a conversation_analytics
object with the data you have requested:
{ "data": [ { "data_points": [ { "start": 1643702400, "end": 1646121600, "conversation": 8500, "conversation_type": "REGULAR", "cost": 88.1010 }, { "start": 1643702400, "end": 1646121600, "conversation”: 1000, "conversation_type": "FREE_TIER", "cost": 0.0000 } { "start": 1643702400, "end": 1646121600, "conversation”: 250, "conversation_type": "FREE_ENTRY_POINT", "cost": 0.0000 } ] } ] }
Request:
curl -i -X GET \
"https://graph.facebook.com/v21.0
/{whatsapp-buiness-account-id}
?fields=conversation_analytics
.start(1685527200)
.end(1685613600)
.granularity(HALF_HOUR)
.conversation_categories(["MARKETING","AUTHENTICATION"])
.dimensions(["CONVERSATION_CATEGORY"])
&access_token={access-token}"
Response:
{ "conversation_analytics": { "data": [ { "data_points": [ { "start": 1685529000, "end": 1685530800, "conversation": 2, "conversation_category": "AUTHENTICATION", "cost": 0.0128 }, { "start": 1685527200, "end": 1685529000, "conversation": 3, "conversation_category": "MARKETING", "cost": 0.0432 } ] } ] }, "id": "102290129340398" }
Request:
curl -i -X GET \
"https://graph.facebook.com/v21.0
/{whatsapp-buiness-account-id}
?fields=conversation_analytics
.start(1685527200)
.end(1685613600)
.granularity(HALF_HOUR)
.conversation_categories(["MARKETING","AUTHENTICATION"])
.dimensions(["CONVERSATION_CATEGORY","CONVERSATION_TYPE"])
&access_token={access-token}"
Response:
{ "conversation_analytics": { "data": [ { "data_points": [ { "start": 1685527200, "end": 1685529000, "conversation": 3, "conversation_type": "REGULAR", "conversation_category": "MARKETING", "cost": 0.0432 }, { "start": 1685529000, "end": 1685530800, "conversation": 2, "conversation_type": "REGULAR", "conversation_category": "AUTHENTICATION", "cost": 0.0128 } ] } ] }, "id": "102290129340398" }
Pricing analytics will be available to you once per-message pricing applies to your rollout group. See Updates to Pricing.
The pricing_analytics
field allows you to get pricing breakdowns for any messages delivered within a specified date range.
GET /<WABA_ID> ?fields=pricing_analytics .start(<START>) .end(<END>) .granularity(<GRANULARITY>) .phone_numbers(<PHONE_NUMBERS>) .country_codes(<COUNTRY_CODES>) .metric_types(<METRIC_TYPES>) .pricing_types(<PRICING_TYPES>) .pricing_categories(<PRICING_CATEGORIES>) .dimensions(<DIMENSIONS>)
Filter | Description | Example Value |
---|---|---|
Array of strings | Optional. The countries for which you would like to retrieve analytics. Provide an array with 2 letter country codes for the countries you would like to include. If not provided, analytics will be returned for all countries you have communicated with. |
|
Array of strings | Optional. List of breakdowns you would like to apply to your metrics. If you send an empty list, we return results without any breakdowns. Values can be:
|
|
UNIX timestamp | Required. UNIX timestamp indicating the end date for the date range you are retrieving analytics for. |
|
String | Required. The granularity by which you would like to retrieve the analytics. Value can be one of:
|
|
Array of strings | Optional. Array of metrics you would like to receive. If you send an empty array, we return results for all metric types. Values can be:
|
|
Array of strings | Optional. An array of phone numbers for which you would like to retrieve analytics. If not provided, data for all business phone numbers associated with your WABA are included. |
|
Array of strings | Optional. Array of pricing categories. If you send an empty array, we return results for all pricing categories. Values can be:
|
|
Array of strings | Optional. Array of pricing types. If you send an empty array, we return results for all pricing types. Values can be:
|
|
UNIX timestamp | Required. UNIX timestamp indicating the start date for the date range you are retrieving analytics for. |
|
String | Required. WhatsApp Business Account ID. |
|
Template analytics describe the number of times a template has been sent, delivered, and read, and the number of times URL buttons or Quick Reply buttons in the template have been clicked.
Data is returned with a daily granularity in the UTC timezone with a lookback of up to 90 days. Template analytics can also be found in the WhatsApp Manager > Message templates > Template details > Insights panel.
MARKETING
or UTILITY
.To report template analytics bugs, submit a Direct Support ticket with the following selections:
You must confirm template analytics on your WhatsApp Business Account before you can get template analytics. You can confirm template analytics using the WhatsApp Manager or the API.
By confirming access via the API, you direct Meta to add insights to your WhatsApp Business Account. These insights include link tracking to report website clicks. You can turn off link tracking on each message template. You also direct Meta to collect and anonymize data from your chats with customers. Meta will anonymize this data to improve services it provides you and other businesses.
To confirm via API, send the following request:
POST /<WHATSAPP_BUSINESS_ACCOUNT_ID>?is_enabled_for_insights=true
Once confirmed, we will begin capturing template analytics for the WhatsApp Business Account. Once confirmed, template analytics cannot be disabled.
Upon success, the API will respond with your WhatsApp Business Account ID. For example:
{ "id": 102290129340398 }
Name | Description | Example Value |
---|---|---|
UNIX Timestamp | Required. The start timestamp for the date range you are retrieving analytics for. As template analytics are being provided with a daily granularity in the UTC timezone, a start timestamp other than 0:00 UTC would be corrected to its prior 0:00 UTC. |
|
UNIX Timestamp | Required. The end date for the date range you are retrieving analytics for. As template analytics are being provided with a daily granularity in the UTC timezone, an end timestamp other than 0:00 UTC would be corrected to its next 0:00 UTC. |
|
Enum | Required. The granularity by which you would like to retrieve the analytics. Value must be |
|
Array of IDs | Required. An array of template IDs for which you would like to retrieve analytics for. Maximum 10. |
|
Array of enums | Optional.
The types of metrics which you want to retrieve. If omitted or an empty array, analytics for all metric types will be returned. Possible values:
|
|
Scenario: Given a 1-day timeframe, get all template analytics metric types for an authentication template and a marketing template with a URL button.
Example Request:
curl -g 'https://graph.facebook.com/v21.0
/109259195336416/template_analytics?start=1718064000&end=1718122745&granularity=daily&metric_types=cost%2Cclicked%2Cdelivered%2Cread%2Csent&template_ids=[1421988012088524%2C2632273056924580]' \
-H 'Authorization: Bearer EAAJB...'
Example Response:
{ "data": [ { "granularity": "DAILY", "product_type": "cloud_api", // Only available to businesses in Marketing Messages Lite API alpha "data_points": [ { "template_id": "1421988012088524", "start": 1718064000, "end": 1718150400, "sent": 1, "delivered": 1, "read": 1, "cost": [ { "type": "amount_spent", "value": 0.01 }, { "type": "cost_per_delivered", "value": 0.01 } ] }, { "template_id": "2632273056924580", "start": 1718064000, "end": 1718150400, "sent": 1, "delivered": 1, "read": 1, "clicked": [ { "type": "quick_reply_button", "button_content": "Contact Support", "count": 108 }, { "type": "unique_url_button", "button_content": "Tell me more", "count": 16 } ], "cost": [ { "type": "amount_spent", "value": 0.03 }, { "type": "cost_per_delivered", "value": 0.03 }, { "type": "cost_per_url_button_click", "value": 0.03 } ] } ] } ], "paging": { "cursors": { "before": "MAZDZD", "after": "MjQZD" } } }
Cost metrics are returned as an array of cost objects, each with a type and value. Types can be:
amount_spent
— Total amount spent on conversations opened within the start
and end
timeframe as a result of sending the template. See Opening Conversations.cost_per_delivered
— The amount_spent
value divided by the number of times the template was delivered within the start
and end
timeframe.cost_per_url_button_click
— The amount_spent
value divided by the number of times the template's URL button was clicked, within the start
and end
timeframe. Quick reply button clicks are not included. Object omitted if the template does not have a URL button.Click metrics are returned as an array of JSON objects each with a type and value. Clicks are only returned for URL buttons and quick-reply buttons in templates categorized as MARKETING
or UTILITY
.
Types can be:
url_button
— The total number of clicks on the url button.unique_url_button
— Unique clicks track the number of distinct WhatsApp accounts that have clicked on a button. This metric helps you understand how many individual users are engaging with your CTAs, while eliminating duplicate clicks from the same recipient and providing an accurate measurement of engagement.You can disable button click tracking on an individual template by setting its cta_url_link_tracking_opted_out
field to true
. Once disabled, the API will no longer return the clicked property in template analytics or display button engagement/clicks in the WhatsApp Manager when viewing the template's insights.
POST /<TEMPLATE_ID> ?cta_url_link_tracking_opted_out=<OPT_OUT> &category=<TEMPLATE_CATEGORY>
Placeholder | Description | Example Value |
---|---|---|
Template ID | Required. Template ID. |
|
Boolean | Required. Indicates if template button click tracking is disabled. Set to This value is set to |
|
String | Required. Template's current category. If you set the template category to a value other than its current category, the template status will be set to |
|
curl -X POST 'https://graph.facebook.com/v21.0
/245435364965041?cta_url_link_tracking_opted_out=true&category=marketing' \
-H 'Authorization: Bearer EAAJB...'
Upon success, the API will respond with:
{ "success": true }
For a list of all possible values for each field, refer to the Graph API reference of the WhatsApp Business Account Analytics field.