On-demand reporting queries
On-demand reporting queries use GraphQL to return aggregated reporting data directly in the API response. You can use these queries to track campaign performance, spending, and other metrics without scheduling a report or downloading a file.
Each entity query (advertiser, campaign, and so on) contains a reporting object that has several reporting types as fields. These fields include different types of reports such as generalReporting, deviceReporting, and geoReporting. Available reporting types vary by entity. The metrics and dimensions you include determine how results are aggregated and grouped.
Here's what you need to know about on-demand reporting queries:
- Reporting queries provide on-demand access to a subset of key metrics available in scheduled reports. For example,
impressions,cpm, andclicks. - Reporting query data refreshes every 30 minutes.
- Each reporting type has its own dataset, and each dataset might be updated at a different rate.
- Pagination for reporting queries has a maximum page size of 1000 records.
Reporting data availability
Reporting queries are supported at specific entity levels. The available reporting types, metrics, and dimensions vary by level.
Reporting queries are available at the following entity levels:
- Partner
- Advertiser
- Campaign
- Campaign flight
- Campaign group
- Ad group
- Ad group flight
- Creative
The reporting types available at each level might differ.
TIP: To see which reporting types are supported for a given entity, include the
reportingobject in your entity query. Each available reporting type appears as a field (for example,generalReportingorgeoReporting) and exposes the supported metrics and dimensions.
For details about how to construct these queries, see Create a reporting query.
Time range limits
On-demand reporting queries support different time ranges depending on the reporting type and the time granularity you request. If you include a where.date filter, the maximum lookback period and date range per query are determined by the following:
- The reporting type (for example,
generalReporting) - The time dimension specified in the time field (such as
dayorhour)
Most reporting types support the following lookbacks:
- Up to 31 days of daily data
- Up to 100 hours of hourly data
The following table lists the time range limits for the generalReporting type.
| Time Dimension Value | Maximum Lookback | Maximum Date Range per Query |
|---|---|---|
| None | Lifetime | 31 days |
day |
1 year | 31 days |
hour |
30 days | 48 hours |
IMPORTANT: If you specify a date range outside the supported limits, the query returns a validation error.
Create a reporting query
To create a reporting query, include the following fields in the reporting object:
- A reporting type field, such as
generalReporting,geoReporting,deviceReporting, and so on.TIP For most use cases, start with
generalReporting, which includes the broadest set of metrics. Use other reporting types for more specific breakdowns, such as by device or geography. - The
nodesobject with the following fields:metrics: to specify which metrics to return.dimensions: to group the data. Use multiple dimensions for additional data breakdown.
You can further refine or inspect the results using the following optional fields and arguments:
- To filter results by date, status, and other supported fields, use the
whereargument. For supported date ranges, see Time range limits. - To see when the data was last refreshed, include the
metadata.lastUpdatedAtfield.
TIP: You can also run multiple queries for multiple entities at once. For details, see GraphQL bulk operations: Queries.
Here's an example advertiser query that retrieves bidding and spending report data by device type for each day.
query GetDeviceBidsAndSpendExample($advertiserId: ID!) {
advertiser(id: $advertiserId) {
reporting {
deviceReporting {
nodes {
metrics {
bids
spend {
advertiserCurrency
}
}
dimensions {
deviceType
time {
day
}
}
}
}
}
}
}
The following sections provide common examples for on-demand reporting queries at different entity levels.
Look up live campaigns with the highest CPM
Here's an example advertiser query that retrieves a list of live campaigns that have the highest CPM.
query GetHighestCpmLiveCampaignsExample($advertiserId: ID!) {
advertiser(id: $advertiserId) {
campaigns(
first: 25
where: { status: { in: [LIVE, LIVE_NOT_SPENDING] } }
order: [
{
campaignReporting: {
metric: CPM_IN_ADVERTISER_CURRENCY
direction: DESC
}
}
]
) {
nodes {
name
reporting {
generalReporting {
nodes {
metrics {
cpm {
advertiserCurrency
}
}
}
}
}
}
}
}
}
Look up campaign flight ROAS performance
Here's an example campaign query that retrieves the ROAS for each day of the current campaign flight.
query GetCurrentFlightROASOverTimeExample($campaignId: ID!) {
campaign(id: $campaignId) {
currentFlight {
reporting {
generalReporting {
nodes {
dimensions {
time {
day
}
}
metrics {
roas {
advertiserCurrency
}
}
}
}
}
}
}
}
Look up campaign publisher spending
Here's an example campaign query that retrieves a list of publishers a campaign spends on most and the CPA for each publisher.
query GetTop10PublishersExamples($campaignId: ID!) {
campaign(id: $campaignId) {
reporting {
publisherReporting(
first: 10
where: {
date: { gte: "2026-03-01T00:00:00Z", lt: "2026-04-01T00:00:00Z" }
}
order: [{ spend: { advertiserCurrency: DESC } }]
) {
nodes {
dimensions {
publisherProperty {
name
}
}
metrics {
spend {
advertiserCurrency
}
cpa {
advertiserCurrency
}
}
}
}
}
}
}
Look up ad group device performance
Here's an example adGroup query that returns ad group performance across different device makes and models.
query GetMetricsByDeviceMakeAndModelExample($adGroupId: ID!) {
adGroup(id: $adGroupId) {
reporting {
deviceReporting(
where: {
date: { gte: "2026-03-01T00:00:00Z", lt: "2026-03-08T00:00:00Z" }
}
) {
nodes {
dimensions {
deviceMakeName
deviceModelName
}
metrics {
bids
spend {
advertiserCurrency
}
cpm {
advertiserCurrency
}
impressions
}
}
metadata {
lastUpdatedAt
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}
FAQs
The following are frequently asked questions about on-demand reporting queries.
How do I know if my data is current?
To check when the data was last updated, include the metadata.lastUpdatedAt field in your query. This helps you determine whether a drop in performance reflects actual campaign activity or a delay in the data.
Can on-demand reporting queries replace scheduled reports?
No. On-demand reporting queries have only a subset of the metrics in scheduled reports. While reporting queries have metrics that are available approximately every 30 minutes, scheduled reports are better suited for large datasets, historical analysis, and file-based workflows. For details, see Reports.
What is the maximum lookback period for reporting queries?
The maximum lookback period depends on the dataset and granularity you want to retrieve. For details, see Time range limits.
Why are my reporting query results different from my scheduled report data?
Since reporting query data is updated approximately every 30 minutes, results might not match scheduled report data pulled at a different point in time.
Why does the same metric return different values in different reporting types?
Each reporting type has its own dataset, which might be updated at a different rate. As a result, the same metric from two different reporting types might return different values.
TIP: To see when a reporting type was last updated, include the
metadata.lastUpdatedAtfield in your query.
How do I find out what metrics are available for a reporting type?
Include the reporting object in your entity query. Each reporting type exposes its available metrics through the metrics field.
How do I find out which reporting types are available for an entity?
Include the reporting object in your entity query. The available reporting types appear as fields and vary by entity level. See also Reporting data availability.