Analytics metrics help partners and advertisers understand the performance of the content they promote on X. This includes information such as impressions, clicks, video views, and spend. In addition, partners and advertisers are able to get detailed metrics for various segments of the audiences they reach.
The Ads API supports two ways of retrieving detailed campaign performance metrics: synchronously and asynchronously. With synchronous analytics calls, the requested metrics are returned in the response. With the asynchronous analytics endpoints, the requested metrics are available in a downloadable results file after the associated “job” has finished processing. The synchronous endpoint supports short time ranges and is ideal for real-time campaign optimizations. The asynchronous endpoints support much longer time ranges and are, thus, intended for fetching much more data, ideal for generating reporting or historical backfills.
The differences between the synchronous and asynchronous analytics endpoints are summarized in the following table. This information is intended to help developers choose which set of endpoints to use.
Feature | Synchronous | Asynchronous |
---|---|---|
Rate limiting | User-level: 250 requests / 15 minutes | Account-level: 100 concurrent* jobs |
Time range | 7 days | 90 days (non-segmented) 45 days (segmented) |
Segmentation | No | Yes |
Response returns | Metrics data | Processing state of the job** |
Recommended use case | Real-time optimization User interface requests | Regularly-scheduled syncing Backfilling historical data |
* This refers to the maximum number of jobs that may be in a processing state at any given time.
** Once the job has successfully finished processing, a URL is returned. This is where the compressed (gzip) results file can be downloaded from.
Outside of this, the endpoints offer the same functionality.
There are three major analytics use cases.
The synchronous analytics endpoint may be used for real-time optimization to update campaigns based on changes to metrics within the last 5 to 15 minutes. Either endpoint can be used for analytics synchronization. Keep in mind that the desired time range and whether segmentation is required will determine which endpoint to use. New account on-boarding should only be done using the asynchronous analytics endpoints. (The synchronous analytics endpoint should never be used for retrieving large amounts of data.)
The asynchronous analytics endpoints can power dashboards and other UI elements if metrics are synced with a backend process. Your implementation should avoid calling the asynchronous analytics endpoints to fulfill user interface requests.
Analytics requests are scoped to ads accounts and, thus, require the account ID in the resource path. Request options, listed below, are specified as query parameters. The following types of values are required.
Use the start_time
and end_time
request parameters to specify a time range. These values must be aligned with the specified granularity in the following way.
TOTAL
: specify any time range (within the endpoint’s limits)DAY
: both the start time and end time values must be aligned with midnight in the account’s time zoneHOUR
: specify any time range (within the endpoint’s limits)End time is exclusive. For example, a request with start_time=2019-01-01T00:00:00Z
and end_time=2019-01-02T00:00:00Z
will return a single day’s worth of analytics metrics (not two) as this time range covers only a 24 hour period.
Segmentation
Available only through our asynchronous analytics endpoints, segmentation allows partners and advertisers to retrieve metrics broken out particular targeting values. To request segmented metrics, use the segmentation_type
request parameter. For more details on segmentation options, see Metrics and Segmentation.
Why don’t the Ads API numbers match what’s shown in the X Ads UI?
ALL_ON_TWITTER
and PUBLISHER_NETWORK
, SPOTLIGHT
, and TREND
.Why do the numbers change depending on when I request data?
How can I determine which entity IDs to request for a specific time period?
Why are all of the values in the analytics response null
?
Why does the API show null
values while the UI shows 0s?
How can I request metrics associated with a granular placement, such as the X timeline?
ALL_ON_TWITTER
and PUBLISHER_NETWORK
, SPOTLIGHT
, and TREND
(i.e., the X Audience Platform)Is it possible to retrieve metrics for deleted or paused entities?
Why don’t the segmented values match the non-segmented ones?
Is it possible to request data segmented by multiple dimensions?
Some best practices when collecting analytics data from the Ads API.
HTTP 429
status code), you must inspect the x-rate-limit-reset
header and retry only at or after the time indicated.retry-after
header and retry only after the time indicated.billed_charge_local_micro
.billed_charge_local_micro
metric is an estimate for up to 3 days after the data is returned.end_time
) and for billable events that are determined to be junk. This metric changes minimally after 24 hours.start_time
and an end_time
.HOUR
granularity, as you can always aggregate and roll metrics up to get DAY
and TOTAL
granularity.line_items
and promoted_tweets
level, as you can always aggregate and roll these metrics up to get totals across the entire ads entity hierarchy (i.e. for the campaign, funding instrument or account levels).INTERESTS
can be delayed for up to 12 hours.start_time
and end_time
chunks.You can find a sample script demonstrating some of these best practices (fetch_stats
) on our ads-platform-tools github repository.
Which metrics are applicable for an entity depends on the campaign objective. Use this guide to determine the relevant metric groups to fetch for each objective type, as well as how additional derived metrics can be calculated.
ENGAGEMENTS
Relevant metric groups:ENGAGEMENT
and BILLING
. MEDIA
is also applicable if media is used in creatives.
Derived Metric | Exposed Metric Calculation |
Engagement Rate | engagements/impressions |
CPE | billed_charge_local_micro/engagements |
Media View Rate | media_views/impressions |
WEBSITE_CLICKS
and WEBSITE_CONVERSIONS
Relevant metric groups:ENGAGEMENT
, BILLING
, and WEB_CONVERSION
. MEDIA
is also applicable if media is used in creatives.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
Click Rate | clicks/impressions |
CPLC | billed_charge_local_micro/clicks |
Total Conversions | conversion_custom + conversion_site_visits + conversion_sign_ups + conversion_downloads + conversion_purchases |
Conversion Rate | Total Conversions / impressions |
CPA | billed_charge_local_micro / Total Conversions |
APP_INSTALLS
and APP_ENGAGEMENTS
Relevant metric groups:ENGAGEMENT
, BILLING
, MOBILE_CONVERSION
, and LIFE_TIME_VALUE_MOBILE_CONVERSION
. MEDIA
and VIDEO
are also applicable if media or video app card is used in creatives.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
App Click Rate | app_clicks/impressions |
CPAC | billed_charge_local_micro/app_clicks |
CPI | billed_charge_local_micro/mobile_conversion_installs |
FOLLOWERS
Relevant metric groups:ENGAGEMENT
and BILLING
. MEDIA
is also applicable if media is used in creatives.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
Follow Rate | follows/impressions |
CPF | billed_charge_local_micro/follows |
Media View Rate | media_views/impressions |
LEAD_GENERATION
Relevant metric groups:ENGAGEMENT
and BILLING
. MEDIA
is also applicable if media is used in creatives.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
Leads | card_engagements |
Lead Rate | card_engagements/impressions |
Cost Per Lead | billed_charge_local_micro/card_engagements |
VIDEO_VIEWS
Relevant metric groups:ENGAGEMENT
, BILLING
, and VIDEO
.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
Video Rate | video_total_views/impressions |
Cost Per View | billed_charge_local_micro/video_total_views |
VIDEO_VIEWS_PREROLL
Relevant metric groups:ENGAGEMENT
, BILLING
, and VIDEO
.
Derived Metric | Exposed Metric Calculation |
CPM | billed_charge_local_micro/impressions/1000 |
Video Rate | video_total_views/impressions |
Cost Per View | billed_charge_local_micro/video_total_views |
This document is an overview of the metrics available from our Analytics for each entity type, as well as the available segmentation for each metrics.
Metric Groups | |||||||
Entity | ENGAGEMENT | BILLING | VIDEO | MEDIA | WEB_CONVERSION | MOBILE_CONVERSION | LIFE_TIME_VALUE_MOBILE_CONVERSION |
ACCOUNT | ✔* | ||||||
FUNDING_INSTRUMENT | ✔* | ✔ | |||||
CAMPAIGN | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
LINE_ITEM | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
PROMOTED_TWEET | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
MEDIA_CREATIVE | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
ORGANIC_TWEET | ✔ | ✔ |
*Some metrics in the ENGAGEMENT
metrics family are not available at the account and funding instrument level. See the ENGAGEMENT
section for details.
ENGAGEMENT
Metric | Description | Segmentation Available | Data Type | Available for Account / Funding Instrument |
engagements | Total number of engagements | ✔ | Array of ints | ✔ |
impressions | Total number of impressions | ✔ | Array of ints | ✔ |
retweets | Total number of retweets | ✔ | Array of ints | ✔ |
replies | Total number of replies | ✔ | Array of ints | ✔ |
likes | Total number of likes | ✔ | Array of ints | ✔ |
follows | Total number of follows | ✔ | Array of ints | ✔ |
card_engagements | Total number of card engagements | ✔ | Array of ints | |
clicks | Total number of clicks, including favorites and other engagements | ✔ | Array of ints | |
app_clicks | Number of app install or app open attempts | ✔ | Array of ints | |
url_clicks | Total clicks on the link or Website Card in an ad, including earned. | ✔ | Array of ints | |
qualified_impressions | Total number of qualified impressions | ✔ | Array of ints | |
carousel_swipes | Total swipes on Carousel images or videos | ✔ | Array of ints |
BILLING
Metric | Description | Segmentation Available | Data Type |
billed_engagements | Total number of billed engagements | ✔ | Array of ints |
billed_charge_local_micro | Total spend in micros | ✔ | Array of ints |
VIDEO
Notice about video metrics definition changes:
The video_total_views
metric within the VIDEO
metrics group will report on any views which are at least 50% in-view for 2 seconds, as per the MRC standard.
Our original video view definition of 100% in view for at least 3 seconds will continue to be available as a new video_3s100pct_views
metric in the VIDEO
metrics group. To continue to bid and be charged based on the original view definition, use the newly available VIEW_3S_100PCT
bid_unit.
Metric | Description | Segmentation Available | Data Type |
video_total_views | Total number of video views | ✔ | Array of ints |
video_views_25 | Total number of views where at least 25% of the video was viewed. | ✔ | Array of ints |
video_views_50 | Total number of views where at least 50% of the video was viewed. | ✔ | Array of ints |
video_views_75 | Total number of views where at least 75% of the video was viewed. | ✔ | Array of ints |
video_views_100 | Total number of views where at least 100% of the video was viewed. | ✔ | Array of ints |
video_cta_clicks | Total clicks on the call to action | ✔ | Array of ints |
video_content_starts | Total number of video playback starts | ✔ | Array of ints |
video_3s100pct_views | Total number of views where at least 3 seconds were played while 100% in view (legacy video_total_views ) | ✔ | Array of ints |
video_6s_views | Total number of views where at least 6 seconds of the video was viewed | ✔ | Array of ints |
video_15s_views | Total number of views where at least 15 seconds of the video or for 95% of the total duration was viewed | ✔ | Array of ints |
MEDIA
Metric | Description | Segmentation Available | Data Type |
media_views | Total number of views (autoplay and click) of media across Videos, Vines, GIFs, and Images. | ✔ | Array of ints |
media_engagements | Total number of clicks of media across Videos, Vines, GIFs, and Images. | ✔ | Array of ints |
WEB_CONVERSION
Metric | Description | Segmentation Available | Data Type |
conversion_purchases | Number of conversions of type PURCHASE and the corresponding sale amount and order quantity | PLATFORMS only | JSON object |
conversion_sign_ups | Number of conversions of type SIGN_UP and the corresponding sale amount and order quantity | PLATFORMS only | JSON object |
conversion_site_visits | Number of conversions of type SITE_VISIT and the corresponding sale amount and order quantity | PLATFORMS only | JSON object |
conversion_downloads | Number of conversions of type DOWNLOAD and the corresponding sale amount and order quantity | PLATFORMS only | JSON object |
conversion_custom | Number of conversions of type CUSTOM and the corresponding sale amount and order quantity | PLATFORMS only | JSON object |
MOBILE_CONVERSION
Mobile conversion stats are available only to advertiser accounts enabled for MACT.
Metric | Description | Segmentation Available | Data Type |
mobile_conversion_spent_credits | Breakdown of mobile conversions of type SPENT_CREDIT by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_installs | Breakdown of mobile conversions of type INSTALL by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_content_views | Breakdown of mobile conversions of type CONTENT_VIEW by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_add_to_wishlists | Breakdown of mobile conversions of type ADD_TO_WISHLIST by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_checkouts_initiated | Breakdown of mobile conversions of type CHECKOUT_INITIATED by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_reservations | Breakdown of mobile conversions of type RESERVATION by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_tutorials_completed | Breakdown of mobile conversions of type TUTORIAL_COMPLETED by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_achievements_unlocked | Breakdown of mobile conversions of type ACHIEVEMENT_UNLOCKED by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_searches | Breakdown of mobile conversions of type SEARCH by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_add_to_carts | Breakdown of mobile conversions of type ADD_TO_CART by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_payment_info_additions | Breakdown of mobile conversions of type PAYMENT_INFO_ADDITION by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_re_engages | Breakdown of mobile conversions of type RE_ENGAGE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_shares | Breakdown of mobile conversions of type SHARE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_rates | Breakdown of mobile conversions of type RATE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_logins | Breakdown of mobile conversions of type LOGIN by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_updates | Breakdown of mobile conversions of type UPDATE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_levels_achieved | Breakdown of mobile conversions of type LEVEL_ACHIEVED by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_invites | Breakdown of mobile conversions of type INVITE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_key_page_views | Breakdown of mobile conversions of type KEY_PAGE_VIEW by post_view and post_engagement | ✔ | JSON object |
mobile_conversion_downloads | Breakdown of mobile conversions of type DOWNLOAD by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_purchases | Breakdown of mobile conversions of type PURCHASE by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_sign_ups | Breakdown of mobile conversions of type SIGN_UP by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
mobile_conversion_site_visits | Breakdown of mobile conversions of type SITE_VISIT by post_view, post_engagement, assisted, order_quantity, and sale_amount | ✔ | JSON object |
LIFE_TIME_VALUE_MOBILE_CONVERSION
Lifetime mobile conversion stats are available only to advertiser accounts enabled for MACT.
Metric | Description | Segmentation Available | Data Type |
mobile_conversion_lifetime_value_purchases | Breakdown of mobile conversions of type PURCHASE | JSON object | |
mobile_conversion_lifetime_value_sign_ups | Breakdown of mobile conversions of type SIGN_UP | JSON object | |
mobile_conversion_lifetime_value_updates | Breakdown of mobile conversions of type UPDATE | JSON object | |
mobile_conversion_lifetime_value_tutorials_completed | Breakdown of mobile conversions of type TUTORIAL_COMPLETED | JSON object | |
mobile_conversion_lifetime_value_reservations | Breakdown of mobile conversions of type RESERVATION | JSON object | |
mobile_conversion_lifetime_value_add_to_carts | Breakdown of mobile conversions of type ADD_TO_CART | JSON object | |
mobile_conversion_lifetime_value_add_to_wishlists | Breakdown of mobile conversions of type ADD_TO_WISHLIST | JSON object | |
mobile_conversion_lifetime_value_checkouts_initiated | Breakdown of mobile conversions of type CHECKOUT_INITIATED | JSON object | |
mobile_conversion_lifetime_value_levels_achieved | Breakdown of mobile conversions of type LEVEL_ACHIEVED | JSON object | |
mobile_conversion_lifetime_value_achievements_unlocked | Breakdown of mobile conversions of type ACHIEVEMENT_UNLOCKED | JSON object | |
mobile_conversion_lifetime_value_shares | Breakdown of mobile conversions of type SHARE | JSON object | |
mobile_conversion_lifetime_value_invites | Breakdown of mobile conversions of type INVITE | JSON object | |
mobile_conversion_lifetime_value_payment_info_additions | Breakdown of mobile conversions of type PAYMENT_INFO_ADDITION | JSON object | |
mobile_conversion_lifetime_value_spent_credits | Breakdown of mobile conversions of type SPENT_CREDIT | JSON object | |
mobile_conversion_lifetime_value_rates | Breakdown of mobile conversions of type RATE | JSON object |
Segmentation reporting allows the retrieval of metrics broken out by the values of a given targeting type. Segmentation is only available through asynchronous analytics queries due to their significant added complexity.
Segmentation not supported for MEDIA_CREATIVE
or ORGANIC_TWEET
entities.
Some segmentation types require additional parameters to be passed in. These are documented below.
When segmenting by CITIES
or POSTAL_CODES
, the API will only returned targeted locations. Region and metro segmentation will return both targeted and non-targeted locations.
Segmentation Type | country param required | platform param required |
AGE | ||
APP_STORE_CATEGORY | ||
AUDIENCES | ||
CITIES | ✔ | |
CONVERSATIONS | ||
CONVERSION_TAGS | ||
DEVICES | ✔ | |
EVENTS | ||
GENDER | ||
INTERESTS | ||
KEYWORDS | ||
LANGUAGES | ||
LOCATIONS | ||
METROS | ✔ | |
PLATFORMS | ||
PLATFORM_VERSIONS | ✔ | |
POSTAL_CODES | ✔ | |
REGIONS | ✔ | |
SLIDES | ||
SIMILAR_TO_FOLLOWERS_OF_USER | ||
TV_SHOWS |
Campaign metrics depend on their campaign objective. Use this guide to determine how to calculcate derived metrics for use based on the objectives in place.
Any metric
without curly brackets is one that is returned by the Ads API analytics endpoints. Any name surrounded by {curley brackets} indicates a derived metric for that category.
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
{Total Engagements} | promoted_account_follows + promoted_tweet_search_engagements + promoted_tweet_timeline_engagements + promoted_tweet_profile_engagements or promoted_account_follows + promoted_tweet_search_clicks + promoted_tweet_search_replies + promoted_tweet_search_retweets + promoted_tweet_search_follows + promoted_tweet_timeline_clicks + promoted_tweet_timeline_replies + promoted_tweet_timeline_retweets + promoted_tweet_timeline_follows + promoted_tweet_profile_clicks + promoted_tweet_profile_replies + promoted_tweet_profile_retweets + promoted_tweet_profile_follows |
{Engagement Rate} | {Total Engagements} / {Impressions} |
billed_charge_local_micro / {Total Engagements} | |
{Media Views} | promoted_tweet_timeline_media_views + promoted_tweet_search_media_views + promoted_tweet_profile_media_views |
{Media View Rate} | {Media Views} / {Impressions} |
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
{Link Clicks} | promoted_tweet_search_url_clicks + promoted_tweet_timeline_url_clicks + promoted_tweet_profile_url_clicks |
{Click Rate} | {Link Clicks} / {Impressions} |
billed_charge_local_micro / {Link Clicks} | |
conversion_site_visits | |
{Conversion Rate} | conversion_site_visits / {Impressions} |
billed_charge_local_micro / conversion_site_visits |
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
{App Clicks} | promoted_tweet_app_install_attempts + promoted_tweet_app_open_attempts + promoted_tweet_timeline_url_clicks + promoted_tweet_search_url_clicks |
{App Click Rate} | {App Clicks} / {Impressions} |
billed_charge_local_micro / {App Clicks} | |
billed_charge_local_micro / mobile_conversion_installs |
Derived Metric | Exposed Metric Calculation |
promoted_account_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
promoted_account_follows | |
{Follow Rate} | promoted_account_follow_rate |
billed_charge_local_micro / promoted_account_follows | |
{Media Views} | promoted_tweet_timeline_media_views + promoted_tweet_search_media_views + promoted_tweet_profile_media_views |
{Media View Rate} | {Media Views} / {Impressions} |
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
promoted_tweet_search_card_engagements + promoted_tweet_timeline_card_engagements + promoted_tweet_profile_card_engagements | |
{Lead Rate} | {Leads} / {Impressions} |
{Cost Per Lead} | billed_charge_local_micro / {Leads} |
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
{Video Views} | promoted_video_total_views |
{Video Rate} | promoted_video_total_views / {Impressions} |
{Cost Per View} | billed_charge_local_micro / promoted_video_total_views |
Derived Metric | Exposed Metric Calculation |
promoted_tweet_search_impressions + promoted_tweet_timeline_impressions + promoted_tweet_profile_impressions | |
billed_charge_local_micro / {Impressions} / 1000 | |
{Qualified Impressions} | promoted_tweet_timeline_qualified_impressions + promoted_tweet_search_qualified_impressions + promoted_tweet_profile_qualified_impressions |
{Qualified Impression Rate} | {Qualified Impressions} / {Impressions} |
{Cost Per 1000 Qualified Impressions } | billed_charge_local_micro / {Qualified Impressions} / 1000 |
For placement_type
of PROMOTED_ACCOUNT
see the FOLLOWERS
objective above. For all other placements with this objective, see ENGAGEMENTS
for the corresponding derived metrics.
The Active Entities endpoint is designed to be used in conjunction with our synchronous and asynchronous analytics endpoints as it provides information about which campaigns to request analytics for. It does this by returning details about ads entities and when their metrics changed. Using this endpoint will greatly simplify your code and analytics fetching logic.
This guide includes information and context about the endpoint and its data source. It also provides usage guidelines and a series of example requests, demonstrating how to use Active Entities in conjunction with our analytics endpoints. The Summary section provides a high-level description of the recommended approach.
Whenever an ads entity metric changes, we record information about that change. These change events are stored in hourly buckets and include details about the entity as well as the time that the change applies to. The latter is necessary because change events do not always correspond to when they were recorded. Billing adjustments are a common reason for this, but there are others, too.
Active Entities requests are scoped under ads accounts and have three required query parameters: entity
, start_time
, and end_time
.
twurl -H ads-api.x.com "/11/stats/accounts/18ce54d4x5t/active_entities?entity=PROMOTED_TWEET&start_time=2019-03-05T00:00:00Z&end_time=2019-03-06T00:00:00Z"
The following entity
values are supported: CAMPAIGN
, FUNDING_INSTRUMENT
, LINE_ITEM
, MEDIA_CREATIVE
, PROMOTED_ACCOUNT
, and PROMOTED_TWEET
. This reflects the entity types that our analytics endpoints support.
The start_time
and end_time
values must be expressed in ISO 8601 and specify which hourly buckets to query. These must be expressed in whole hours.
This endpoint also supports three optional parameters that can be used to filter results: funding_instrument_ids
, campaign_ids
, and line_item_ids
. These work at all levels of the ads hierarchy and with any specified entity
type.
The Active Entities response for the request above is shown below.
The data
array includes an object for every entity that should be included in a subsequent analytics request. You should not request analytics for IDs outside of this set.
Each object includes four fields: entity_id
, activity_start_time
, activity_end_time
, and placements
. The activity start and end times represent the time range that the associated entity’s change events apply to and, thus, determine the dates that should be specified in subsequent analytics requests. The placements
array can include the following values: ALL_ON_TWITTER
, PUBLISHER_NETWORK
, SPOTLIGHT
, and TREND
. It indicates which placements should be requested for the given entity ID.
The Active Entities endpoint should dictate how analytics requests are made. The following usage guidelines are written to support analytics synchronization, enabling partners to keep their data stores in sync with Twitter. In other words, it describes how to perform regularly-scheduled background syncs.
There are two decisions a developer must make.
start_time
and end_time
values.These are discussed in greater detail in each of the two subsections, below, after the summary.
Use the Active Entities endpoint in the following way to dictate how analytics requests are made. Follow this after you’ve decided how often to request active entities information and, thus, how often to pull analytics.
ALL_ON_TWITTER
, one for PUBLISHER_NETWORK
, one for SPOTLIGHT
, and one for TREND
.start_time
and end_time
values.
activity_start_time
. Round this value down.activity_end_time
. Round this value up.start_time
and end_time
values from #3b.placement
value.Please see active_entities.py as an example that uses the Python SDK.
The answer to the first question determines the time range that should be used in Active Entities requests. For example, if requesting active entities information every hour, the time range should be an hour. If requesting active entities information once a day, the time range should be a day. In other words, time ranges should be selected such that the current request’s start_time
is equal to the previous request’s end_time
.
Note: A time window should only be requested once. Requesting a time window more than once will lead to unnecessary analytics requests. (Exception below.)
For partners wishing to request analytics multiple times an hour for the current hour, the same pattern applies—the frequency determines the time range. The table below shows example Active Entities start and end timestamps for this scenario.
Request time | start_time timestamp | end_time timestamp |
00:15:00 | 00:00:00 | 00:15:00 |
00:30:00 | 00:15:00 | 00:30:00 |
00:45:00 | 00:30:00 | 00:45:00 |
01:00:00 | 00:45:00 | 01:00:00 |
Given the way that change events are stored, all four Active Entities requests above query the same hourly bucket, which is necessary for this use case. However, after the current hour, this hourly bucket should no longer be queried.
We recommend the following approach to working with activity start and end times. Across all objects in the Active Entities response, find the minimum activity_start_time
and the maximum activity_end_time
. Modify these values by rounding the minimum activity start time down and rounding the maximum activity end time up. Specifically, set the timestamps to zero for both and add one day to the end time, as illustrated in the following table. These are the start and end times that should be specified in subsequent analytics requests.
Min, max activity times | Derived times |
2019-03-04T20:55:20Z 2019-03-05T14:40:59Z | 2019-03-04T00:00:00Z 2019-03-06T00:00:00Z |
Note: It’s important to include the timestamps with hours, minutes, and seconds set to zero. Otherwise, if only the date is passed in, we will assume you’re requesting analytics starting and ending at midnight in the ads account’s timezone, which may not be desirable. For example, if the minimum activity start time is 2019-02-28T01:30:07Z and the timestamp is omitted for an ads account with an offset of -08:00:00, the analytics request will miss changes that happened between 01:30 and 08:00.
Alternatively, if you would prefer to request analytics for just the returned activity time window without expanding to full days, you can. Using this approach, the derived start and end times would be 2019-03-04T20:00:00Z and 2019-03-05T15:00:00Z, respectively. (Note that ranges like these are not accepted if you specify DAY
granularity in the analytics request.)
This section demonstrates how to use Active Entities in conjunction with the synchronous analytics endpoint. (The responses have been slightly modified for readability.) In this example, the Active Entities endpoint is called at the top of each hour, with each request looking at the previous hour. The response determines how the synchronous analytics endpoint is used.
The first Active Entities request is made at 03:00:00. The response indicates that line item dvcz7’s metrics changed and that those change events apply to the window between 02:02:55 and 02:28:12.
Based on these activity start and end times and using the approach described above, the analytics start_time
and end_time
values are set to 2019-02-11T00:00:00Z and 2019-02-12T00:00:00Z, respectively. We see that the third element in each of the metrics arrays below are non-zero, as we expected based on the active entities information.
The next Active Entities request happens at 04:00:00 and only looks at the previous hour. As mentioned above, a time window should only be requested once. Based on the response, we see that change events for this line item apply to both 02:00:00 and 03:00:00. In the subsequent analytics request, we expect to see changes for both hours.
In addition to seeing non-zero metrics for 03:00:00, we see that the impressions, spend, and MRC video views have been updated from their previous values. Impressions, for example, are now 2,995 for the 02:00:00 hour, up from 2,792. This demonstrates how change events that were recorded during the 03:00:00 hour apply to the 02:00:00 hour.
The Active Entities request at 05:00:00, again looking at just the previous hour, shows that change events apply to the 03:00:00 hour only. The changes to analytics metrics in the subsequent request reflect this.
The analytics response shows that only metrics for the 03:00:00 hour have changed; the values for the 02:00:00 hour are the same as they were during the previous analytics request.
Finally, at 06:00:00 we see that there are no additional change events. Note: This does not imply that metrics for this line item cannot change in the future, though.
The asynchronous analytics endpoints allow partners and advertisers to request metrics by submitting create requests that the server processes asynchronously. (We refer to these as asynchronous analytics “jobs.”) With this approach, the client’s connection does not need to remain open until the request has been fulfilled.
These endpoints, like their synchronous counterpart, allow partners and advertisers to request detailed statistics on campaign performance. They support requesting data for accounts, funding instruments, campaigns, line items, promoted Tweets, and media creatives. The difference between these and the synchronous endpoint is that the asynchronous analytics endpoints support longer date ranges, up to 90 days, as well as segmentation. Additional details on the differences between the two can be found on our Analytics Overview page.
Unlike our synchronous endpoints, rate limiting is based on the number of concurrent jobs for a given account. In other words, it’s based on the number of jobs that can be in a processing state at a given time. We count this at the ads account level.
Retrieving campaign metrics using the asynchronous analytics endpoints is a multi-step process. It involves creating a job, checking whether the job has finished processing, and, finally, downloading the data. The data file must be decompressed. The four specific steps are outlined below.
The response object returned in the data file has the same JSON schema as the synchronous analytics endpoint’s response.
Segmented campaign metrics are only available via the asynchronous analytics endpoints. Campaign metrics can be broken out by location, gender, interest, keyword, and more. For a full list of options, see the Metrics and Segmentation page. In order to request segmented metrics, use the segmentation_type
request parameter when creating the job.
This section demonstrates how to use the asynchronous analytics endpoints.
Start by creating a job using the POST stats/jobs/accounts/:account_id endpoint. The example below requests engagement metrics—such as impressions, likes, clicks, etc.—for a specific line item over a week’s time. (Note that the requested time range goes up to, but does not include March 20th since the timestamp is set to midnight.)
This response does not return the line item metrics. It simply provides information about the job you just created. The job ID is needed to check on the status of the job. This is shown in both the id
and id_str
response attributes.
Next, you’ll want to check whether the job you’ve created using the id_str
from the previous response, has finished processing as indicated by "status": "SUCCESS"
in the response. This means the data is ready to download. The url
field contains the download link.
While we’re passing in a single job ID in the above example, in practice, you’ll want to use the job_ids
parameter to check on the status of multiple jobs at a time by specifying up to 200 job IDs.
Next, download the data file using the listed url
value.
Finally, unzip the file.
The contents of the file are shown below.
Retrieve reach and average frequency analytics for specified campaigns.
https://ads-api.x.com/stats/accounts/:account_id/reach/campaigns
Name | Description |
---|---|
account_id required | The identifier for the leveraged account. Appears within the resource’s path and is generally a required parameter for all Advertiser API requests excluding GET accounts. The specified account must be associated with the authenticated user. Type: string Example: 18ce54d4x5t |
campaign_ids required | Scope the response to just the desired campaigns by specifying a comma-separated list of identifiers. Up to 20 IDs may be provided. Note: Up to 20 campaign IDs may be provided. Type: string Example: 8fgzf |
end_time required | Scopes the retrieved data to the specified end time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-26T07:00:00Z |
start_time required | Scopes the retrieved data to the specified start time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-19T07:00:00Z |
GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t/reach/campaigns?campaign_ids=8fgzf&start_time=2017-05-19&end_time=2017-05-26
Retrieve reach and average frequency analytics for specified funding instruments.
https://ads-api.x.com/stats/accounts/:account_id/reach/funding_instruments
Name | Description |
---|---|
account_id required | The identifier for the leveraged account. Appears within the resource’s path and is generally a required parameter for all Advertiser API requests excluding GET accounts. The specified account must be associated with the authenticated user. Type: string Example: 18ce54d4x5t |
funding_instrument_ids required | Scope the response to just the desired funding instruments by specifying a comma-separated list of identifiers. Up to 20 IDs may be provided. Note: Up to 20 funding instrument IDs may be provided. Type: string Example: lygyi |
end_time required | Scopes the retrieved data to the specified end time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-26T07:00:00Z |
start_time required | Scopes the retrieved data to the specified start time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-19T07:00:00Z |
Retrieve synchronous analytics for the current account. A maximum time range (end_time
- start_time
) of 7 days is allowed.
https://ads-api.x.com/12/stats/accounts/:account_id
Name | Description |
---|---|
account_id required | The identifier for the leveraged account. Appears within the resource’s path and is generally a required parameter for all Advertiser API requests excluding GET accounts. The specified account must be associated with the authenticated user. Type: string Example: 18ce54d4x5t |
end_time required | Scopes the retrieved data to the specified end time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-26T07:00:00Z |
entity required | The entity type to retrieve data for. Type: enum Possible values: ACCOUNT , CAMPAIGN , FUNDING_INSTRUMENT , LINE_ITEM , ORGANIC_TWEET , PROMOTED_ACCOUNT , PROMOTED_TWEET , MEDIA_CREATIVE |
entity_ids required | The specific entities to retrieve data for. Specify a comma-separated list of entity IDs. Note: Up to 20 entity IDs may be provided. Type: string Example: 8u94t |
granularity required | Specify how granular the retrieved data should be. Type: enum Possible values: DAY , HOUR , TOTAL |
metric_groups required | The specific metrics that should be returned. Specify a comma-separated list of metric groups. For more information see Metrics and Segmentation. Note: MOBILE_CONVERSION data should be requested separately.Type: enum Possible values: BILLING , ENGAGEMENT , LIFE_TIME_VALUE_MOBILE_CONVERSION , MEDIA , MOBILE_CONVERSION , VIDEO , WEB_CONVERSION |
placement required | Scopes the retrieved data to a particular placement. Note: Only a single value accepted per request. For entities with both X and X Audience Platform placement, separate requests are required, one for each placement value. Type: enum Possible values: ALL_ON_TWITTER , PUBLISHER_NETWORK , SPOTLIGHT , TREND |
start_time required | Scopes the retrieved data to the specified start time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-19T07:00:00Z |
Retrieve details about which entities’ analytics metrics have changed in a given time period.
This endpoint should be used in conjunction with our analytics endpoints. The results of this endpoint indicate which ads entities to request analytics for. See our Active Entities Guide for usage guidelines.
Change events are available in hourly buckets.
start_time
and end_time
values specify which hourly buckets to query.data
array will include an object for every entity that should be included in subsequent analytics requests.activity_start_time
and activity_end_time
values.
Note: A maximum time range (end_time
- start_time
) of 90 days is allowed.
https://ads-api.x.com/12/stats/accounts/:account_id/active_entities
Name | Description |
---|---|
account_id required | The identifier for the leveraged account. Appears within the resource’s path and is generally a required parameter for all Advertiser API requests excluding GET accounts. The specified account must be associated with the authenticated user. Type: string Example: 18ce54d4x5t |
end_time required | Scopes the retrieved data to the specified end time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-26T07:00:00Z |
entity required | The entity type to retrieve data for. Type: enum Possible values: CAMPAIGN , FUNDING_INSTRUMENT , LINE_ITEM , MEDIA_CREATIVE , PROMOTED_ACCOUNT , PROMOTED_TWEET |
start_time required | Scopes the retrieved data to the specified start time, expressed in ISO 8601. Note: Must be expressed in whole hours (0 minutes and 0 seconds). Type: string Example: 2017-05-19T07:00:00Z |
campaign_ids optional | Scope the response to just entities associated with desired campaigns by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided. Note: Exclusive with funding_instrument_ids and line_item_ids .Type: string Example: 8wku2 |
funding_instrument_ids optional | Scope the response to just entities associated with desired funding instruments by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided. Note: Exclusive with campaign_ids and line_item_ids .Type: string Example: lygyi |
line_item_ids optional | Scope the response to just entities associated with desired line items by specifying a comma-separated list of identifiers. Up to 200 IDs may be provided. Note: Exclusive with campaign_ids and line_item_ids .Type: string Example: 8v7jo |
GET https://ads-api.x.com/12/stats/accounts/18ce54d4x5t/active_entities?entity=PROMOTED_TWEET&start_time=2019-02-28&end_time=2019-03-01