Use a synchronous metrics to retrieve campaign delivery and attribution metrics in a single, low-latency HTTP request with no job polling required. Results are returned directly in the response body of your GET Get synchronous metrics call, typically within 3 seconds.
This is designed to be used for short timeframes (up to 7 days) and with a fixed set of dimensions. You should use this when you need fast, lightweight data for dashboards and real-time campaign optimization. For longer lookback windows, or for data that needs segmentation, use asynchronous reports instead.
When to use synchronous metrics vs. asynchronous reports
| Use case | Recommended endpoint | Why |
|---|---|---|
| Real-time campaign optimization. Check today's metrics and adjust active campaigns. | Synchronous metrics | Sub-3-second response; no job queue wait. |
| Dashboard UI data refresh | Synchronous metrics | Fast enough for interactive experiences; supports day-level granularity. |
| Regularly scheduled background syncs (e.g. nightly pipeline pulling last 7 days) | Synchronous metrics or asynchronous reports | You can use either approach but synchronous metrics should be used for a time range of ≤ 7 days with no segmentation. |
| Historical data backfill for a new account (months of data) | Asynchronous reports | Synchronous metrics is capped at 7 day so large pulls of data must be done asynchronously. |
| Segmented reports (by placement, geo, audience) | Asynchronous reports | Asynchronous reports supports segmentation parameters needed for this volume of data, synchronous doesn’t. |
| CSV export | Asynchronous reports | Results are written to a downloadable file, which isn't suited for synchronous metrics. |
Only asynchronous reports should be used for large volumes of data. Synchronous metrics are capped at 7 days. Don't repeatedly query for data that is older than 30 days. This data won't change and should be stored locally.
Key characteristics at a glance
| Attribute | Synchronous metrics | Asynchronous reports |
|---|---|---|
| Max time range | 7 days | 13 months |
| Supported granularity | Day, Total | Day, Total, Hour |
| Segmentation | Not supported | Supported (geo, etc.) |
| Data retention | 37 months | 37 months |
| Query response SLA | < 3 seconds | ~ 1 hour |
Get synchronous metrics
To create a synchronous metrics make a GET Get synchronous metrics call and include the following in your request body parameters:
account_uid- The unique identifier of the account to scope the metrics by.entity- The type of entity to collect metrics on:account,campaign,ad_group,ad,creative. If account, thenaccount_uidvalue must be a single UID.entity_uids- A comma-separated list of entity unique identifiers to filter by. When entity isaccount,entity_uidsmust be a single uid equal to the value of theaccount_uid.event_group_uids- A comma-separated list of event group UIDs to filter by.start_date- The start date of the metrics (YYYY-MM-DD). Earliest allowed date is 37 months before today; must not be after today. Inclusive.end_date- The end date of the metrics (YYYY-MM-DD). Must be on or afterstart_date. Data from your end date is included in the results. Inclusive.end_datecan be no more than 6 days afterstart_date, the maximum date range is 7 days.granularity- Time granularity for the metrics data. Accepted values areday(per-day breakdown) ortotal(aggregate for the provided date range). Required on the first page request; ignored when paginating withcursor. Maximum date range is 7 days.attributed_events_by- Attribution method required foractionandcpafields. Determines whether attributed events are measured by when the ad was seen (time_of_impression) or when the user converted (time_of_conversion). Ignored when paginating withcursor. Defaults totime_of_impressionif not specified.
Note: The asynchronous reports endpoint and the Ads Manager UI currently only provide
time_of_conversionreporting.
fields- A comma-separated list of field names to include in the metrics. At least one metric is required; dimensions alone are not valid.actionandcpafields follow theaction_{name}andcpa_{name}naming pattern. Theclicksfield is not supported on this endpoint. Ignored when paginating withcursor. To see all available fields, callGETsynchronous metrics fields parameters first.cursor- Pagination token for retrieving the next page of results. To paginate your metrics, pass themeta.pagination.next_cursorvalue from the response of the previousGETget synchronous metrics call into this parameter. Valid for 60 minutes after the first-page response. Usecursortogether withlimiton follow-up page requests only.limit- Number of results to return per page. Accepted range is 1-10,000. Limits the number of entities per page, not individual time-series rows within an entity. Default is 100.
A successful call returns your metrics data in the response body.
Dimensions
The synchronous endpoint supports limited dimensions to guarantee low latency.
| Dimension | Allowed values | Description |
|---|---|---|
entity | account, campaign, ad_group, ad, creative | The level of the hierarchy at which to aggregate results |
granularity | day, total | Whether to break results out by day or aggregate for the provided date range |
attributed_events_by | by_impression_time, by_conversion_time | Whether attributed actions are counted at the time the ad was seen or the time the conversion occurred |
Fields
Core metrics
| Name | Description |
|---|---|
| impressions | Number of times an ad was displayed |
| billed_local_micro_spend | Total amount billed in local currency, expressed in micros (1/1,000,000 of the currency unit) |
| cpm | Cost per thousand impressions |
| video_view_25pct | Number of times a video ad was viewed to at least 25% completion |
| video_view_50pct | Number of times a video ad was viewed to at least 50% completion |
| video_view_75pct | Number of times a video ad was viewed to at least 75% completion |
| video_view_100pct | Number of times a video ad was viewed to at least 100% completion |
| vcr | Video Completion Rate: percentage of video ads watched to 100% |
| cpcv | Cost Per Completed View: average cost for each fully completed video view |
Action fields
| Name | Description |
|---|---|
| action_achieve_level | User reached a level milestone in a game or app |
| action_ad_response | User engaged with or responded to an ad |
| action_add_payment_info | User added payment information |
| action_add_to_cart | User added an item to their cart |
| action_add_to_wishlist | User added an item to a wishlist |
| action_app_install | User installed an app |
| action_authentication | User completed a login or authentication event |
| action_complete_registration | User completed a registration form |
| action_contact | User initiated contact with the advertiser |
| action_customize_product | User customized a product |
| action_donate | User completed a donation |
| action_download | User downloaded content or a file |
| action_find_location | User looked up a physical store or location |
| action_first_video_view | User viewed a video for the first time |
| action_initiate_checkout | User began the checkout process |
| action_lead | User submitted a lead form |
| action_link_click | User clicked a link |
| action_page_view | User viewed a page |
| action_place_order | User placed an order |
| action_purchase | User completed a purchase |
| action_qss | User completed a Quality Streaming Session (Roku-specific: a session meeting quality thresholds) |
| action_schedule | User scheduled a recording, appointment, or similar event |
| action_search | User performed a search |
| action_send_to_phone | User sent content or a link to their phone |
| action_session_start | User started an app or content session |
| action_sign_up | User signed up for a service or account |
| action_start_trial | User started a free trial |
| action_store_view | User viewed a store or shop page |
| action_submit_application | User submitted an application |
| action_subscribe | User subscribed to a service |
| action_subscription_cancellation | User cancelled a subscription |
| action_subscription_renewal | User renewed a subscription |
| action_unlock_achievement | User unlocked an achievement (gaming context) |
| action_view_cart | User viewed their cart |
| action_view_content | User viewed a specific piece of content, such as a product page, article, or media item |
| action_fqss | User completed a First Quality Streaming Session: their first high-quality stream meeting Roku's quality thresholds |
| action_lapsed_30_streamer | Re-engaged user who had not streamed in the past 30 days |
| action_lapsed_60_streamer | Re-engaged user who had not streamed in the past 60 days |
| action_lapsed_90_streamer | Re-engaged user who had not streamed in the past 90 days |
| action_lapsed_180_streamer | Re-engaged user who had not streamed in the past 180 days |
| action_lapsed_365_streamer | Re-engaged user who had not streamed in the past 365 days |
Order value fields
| Name | Description |
|---|---|
| order_value_purchase | Total order value associated with action_purchase |
Cost Per Action (CPA) fields
| Name | Description |
|---|---|
| cpa_achieve_level | Average cost per user who reached a level milestone in a game or app |
| cpa_ad_response | Average cost per user who engaged with or responded to an ad |
| cpa_add_payment_info | Average cost per user who added payment information |
| cpa_add_to_cart | Average cost per user who added an item to their cart |
| cpa_add_to_wishlist | Average cost per user who added an item to their wishlist |
| cpa_app_install | Average cost per app install |
| cpa_authentication | Average cost per completed login or authentication event |
| cpa_complete_registration | Average cost per completed registration |
| cpa_contact | Average cost per user who initiated contact with the advertiser |
| cpa_customize_product | Average cost per user who customized a product |
| cpa_donate | Average cost per completed donation |
| cpa_download | Average cost per download |
| cpa_find_location | Average cost per user who looked up a physical location |
| cpa_first_video_view | Average cost per user who viewed a video for the first time |
| cpa_initiate_checkout | Average cost per user who began the checkout process |
| cpa_lead | Average cost per lead form submission |
| cpa_link_click | Average cost per link click |
| cpa_page_view | Average cost per page view |
| cpa_place_order | Average cost per order placed |
| cpa_purchase | Average cost per completed purchase |
| cpa_qss | Average cost per Quality Streaming Session |
| cpa_schedule | Average cost per scheduling event |
| cpa_search | Average cost per search performed |
| cpa_send_to_phone | Average cost per user who sent content to their phone |
| cpa_session_start | Average cost per app or content session started |
| cpa_sign_up | Average cost per sign up |
| cpa_start_trial | Average cost per free trial started |
| cpa_store_view | Average cost per store or shop page view |
| cpa_submit_application | Average cost per application submitted |
| cpa_subscribe | Average cost per subscription |
| cpa_subscription_cancellation | Average cost per subscription cancellation |
| cpa_subscription_renewal | Average cost per subscription renewal |
| cpa_unlock_achievement | Average cost per achievement unlocked (gaming context) |
| cpa_view_cart | Average cost per cart view |
| cpa_view_content | Average cost per content view |
| cpa_fqss | Average cost per First Quality Streaming Session |
| cpa_lapsed_30_streamer | Average cost per re-engaged user who had not streamed in the past 30 days |
| cpa_lapsed_60_streamer | Average cost per re-engaged user who had not streamed in the past 60 days |
| cpa_lapsed_90_streamer | Average cost per re-engaged user who had not streamed in the past 90 days |
| cpa_lapsed_180_streamer | Average cost per re-engaged user who had not streamed in the past 180 days |
| cpa_lapsed_365_streamer | Average cost per re-engaged user who had not streamed in the past 365 days |
Paginate metrics with cursor
cursorHow to paginate metrics using the cursor parameter in your request.
When you make a GET get synchronous metrics call, if a successful response includes a meta.pagination.next_cursor value and a "has_more":true then your metrics have at least one more page you can get.
To get the next page, make another GET get synchronous metrics call and include the meta.pagination.next_cursor value from your previous call in the cursor parameter of your new call.
The included object in your response
included object in your responseEvery response includes an included object alongside data and meta. It surfaces the optimization settings (event group and attribution windows) configured for each ad group active within your requested scope and date range, regardless of what entity level you queried.
included.default_optimizations
included.default_optimizationsincluded.default_optimizations is an array where each entry describes the default optimization settings for one ad group:
| Field | Type | Description |
|---|---|---|
ad_group_uid | string | Unique identifier for the ad group |
event_group_uid | string | The event group this ad group is optimizing toward by default |
attribution_window | array of strings | The attribution windows applied to this ad group (e.g., ["click_14d", "view_14d"]) |
Example included block:
"included": {
"default_optimizations": [
{
"ad_group_uid": "PadGrpL1rio1HP",
"event_group_uid": "PaccO8EtiUHh",
"attribution_window": ["click_14d", "view_14d"]
},
{
"ad_group_uid": "PadGrp5o7dgU8h",
"event_group_uid": "PaccO8EtiUHh",
"attribution_window": ["click_14d", "view_14d"]
}
]
}Why this matters: mixed optimization settings
Ad groups within the same campaign or account can be configured to optimize toward different event groups. When you query at the account or campaign level, or when you query multiple ad groups without filtering to a specific event group, the conversion metrics you receive are a sum across all of those ad groups, potentially mixing data from different event groups in a single number. included.default_optimizations makes this transparent.
There are two scenarios to keep in mind:
Scenario 1 - Higher-level query with no event_group_uid filter
Ad Group 1 optimizes toward Event Group A; Ad Group 2 optimizes toward Event Group B. You request entity=account, fields=action_page_view, and don't pass event_group_uids.
The action_page_view count in your response is a sum of page views attributed through Event Group A (via Ad Group 1) and Event Group B (via Ad Group 2). included.default_optimizations shows you which event group each contributing ad group belongs to.
Scenario 2 - Ad group-level query with an explicit events_group_uid filter
You request entity=ad_group, include both Ad Group 1 and Ad Group 2 in entity_uids, set fields=action_page_view, and explicitly filter to Event Group A via event_group_uids.
The returned action_page_view counts for both ad groups will reflect Event Group A only, even for Ad Group 2, which natively optimizes toward Event Group B. included.default_optimizations still shows Ad Group 2's actual default event group, making it visible that its native optimization setting differs from the filter you applied.
Use included.default_optimizations any time you're working with conversion metrics to understand what's behind the numbers you receive and whether mixed event group settings could affect your interpretation.