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 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:

The reporting types available at each level might differ.

TIP: To see which reporting types are supported for a given entity, include the reporting object in your entity query. Each available reporting type appears as a field (for example, generalReporting or geoReporting) 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:

Most reporting types support the following lookbacks:

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:

You can further refine or inspect the results using the following optional fields and arguments:

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.lastUpdatedAt field 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.