---
title: "Flexible live insights query"
method: GET
path: "/v1/ads/insights"
tags: ["Ad Insights"]
---

# Flexible live insights query

`GET /v1/ads/insights`

Live, flexible insights query. The account's platform picks the contract:

**Meta (facebook/instagram)**: forwards caller-chosen `fields`, `breakdowns` and `filtering`
to any Meta insights node and returns Meta's rows verbatim. `objectId` (required) selects the
node; `level` sets row granularity. Semantic validation is Meta's: an unknown field or invalid
breakdown combination returns a 400 carrying Meta's message. For long ranges or agency-scale
accounts prefer the async variant (POST /v1/ads/insights/reports).

**Google Ads (googleads)**: raw GAQL passthrough. Send any read-only GAQL SELECT via `query`
(campaign/keyword/search-term/geo/demographic/asset/shopping resources, `change_event`, any
`segments.*`) and rows come back verbatim (camelCase, counters as strings). Results are paged
at a fixed 10,000 rows; follow `paging.nextPageToken` with `pageToken`. `adAccountId` (alias `customerId`) is only
needed when the connection has several Google Ads accounts. Semantic validation is Google's:
an invalid query returns a 400 carrying Google's message (note: selecting `segments.date`
requires a finite date filter).

Queries run against Google Ads API **v25**, so write GAQL against the v25 field reference.
One exception is translated for backward compatibility: the legacy `campaign.start_date` /
`campaign.end_date` (removed by Google in v23) are rewritten to `campaign.start_date_time` /
`campaign.end_date_time`, and rows still carry `campaign.startDate` / `campaign.endDate` as
`YYYY-MM-DD`. In WHERE, `=`, `<`, `<=`, `>`, `>=`, `BETWEEN` and `IS [NOT] NULL` against a
`'YYYY-MM-DD'` literal are translated; any other form returns Google's 400. New code should
select the `_date_time` fields directly.

## Query parameters

- `accountId` string, required
- `objectId` string
- `query` string
- `adAccountId` string
- `customerId` string
- `pageToken` string
- `level` 'ad' | 'adset' | 'campaign' | 'account'
- `fields` string
- `breakdowns` string
- `actionBreakdowns` string
- `actionAttributionWindows` string
- `actionReportTime` string
- `useUnifiedAttributionSetting` boolean
- `filtering` string
- `datePreset` string
- `fromDate` string, date
- `toDate` string, date
- `timeIncrement` string
- `limit` integer
- `after` string

## Response `200`

Insight rows (raw platform shape)

- object
  - `objectId` string — Meta responses only.
  - `customerId` string — Google responses only: the customer the query ran against.
  - `fieldMask` string, nullable — Google responses only: the selected fields echoed by Google.
  - `data` object[]
  - `paging` object
    - `after` string, nullable — Meta cursor for the next page; null when exhausted.
    - `nextPageToken` string, nullable — Google cursor for the next page; null when exhausted.

## Other responses

- `400` — Invalid input, or the platform rejected the query (unknown field, invalid breakdown combo, malformed GAQL); the message carries the platform's error
- `401` — Unauthorized
- `404` — The account or requested resource was not found or is not accessible. An account ID may have been disconnected and removed. Read GET /v1/accounts for current account IDs.
- `409` — The account exists but is inactive or needs reconnection. Reconnect it, then read GET /v1/accounts for its current account ID before retrying. Code: ads_connection_required.
- `429` — Platform rate limit reached. For Google this is the per-user operations budget or the shared quota; the message says which and when it resets.
- `501` — Only supported on Meta (facebook/instagram) and Google Ads

## Changes

- **2026-09-25** `2c04683ce694` — 8 info
  - added the optional property `details/adAccountId` to the response with the `404` status
  - added the optional property `details/adAccountId` to the response with the `409` status
  - added the optional property `details/createdObjects` to the response with the `404` status
  - added the optional property `details/createdObjects` to the response with the `409` status
  - …4 more
- **2026-09-23** `dd3865482f9f` — 2 info
  - added the new optional `query` request parameter `adAccountId`
  - `query` request parameter `customerId` was deprecated
- **2026-09-16** `3e6ddf2a99ea` — 2 info
  - added the optional property `details/budgetScope` to the response with the `404` status
  - added the optional property `details/budgetScope` to the response with the `409` status
- **2026-09-15** `0dba7d004d75` — 4 info
  - added the optional property `details/quotaExhausted` to the response with the `404` status
  - added the optional property `details/quotaExhausted` to the response with the `409` status
  - added the optional property `details/quotaScope` to the response with the `404` status
  - added the optional property `details/quotaScope` to the response with the `409` status
- **2026-09-10** `e70ed06e7150` — 2 info
  - added the non-success response with the status `404`
  - added the non-success response with the status `409`

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/insights/get.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/b2325332041a?raw)
