Flexible live insights query
Runs a custom performance query against Meta, Google Ads or TikTok and returns the platform's rows as is, for reports the fixed endpoints don't cover.
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.
TikTok (tiktok/tiktokads): passthrough of TikTok's synchronous report
(/report/integrated/get/). Send adAccountId, dataLevel, dimensions, metrics,
fromDate/toDate (TikTok caps the span at 365 days) and optionally filtering in the same
[{"field", "operator", "value"}] shape as Meta (operator is TikTok's filter_type, e.g. IN;
array values are JSON-encoded for TikTok). Rows come back verbatim as
{ dimensions, metrics } with page-number paging.
De-duplicated reach across a set of campaigns, ad groups or ads: filter the set and group by
country_code instead of the entity id. TikTok then counts each person once across the whole
set and range, per country. Example, two campaigns for a month:
dataLevel=AUCTION_CAMPAIGN&dimensions=country_code&metrics=reach,impressions,frequency&fromDate=2026-09-01&toDate=2026-09-30&filtering=[{"field":"campaign_ids","operator":"IN","value":["1876574798182050","1876575504573650"]}].
For a set of ads use dataLevel=AUCTION_AD with ad_ids. A filter on a finer entity than
dataLevel (e.g. ad_ids at AUCTION_CAMPAIGN) returns 400: TikTok would otherwise widen it to
every parent entity containing those ids. When the set delivers in several countries, reach is
per country; summing the rows counts a person reached in two countries twice.
AUCTION_ADVERTISER rejects entity filters.
Authorization
bearerAuth API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.
In: header
Query Parameters
Zernio SocialAccount id (posting or ads variant); its platform selects the Meta, Google or TikTok contract.
Meta only (required there): insights node (act_, campaign id, ad set id or ad id).
Google only (required there): the GAQL SELECT statement to run.
length <= 10000Google: platform ad account ID (Google customer ID, digits only) when the connection has several Google Ads accounts. TikTok (required there): the advertiser id.
TikTok only: report_type.
"BASIC"Value in
- "BASIC"
- "AUDIENCE"
TikTok only (required there): data_level.
Value in
- "AUCTION_ADVERTISER"
- "AUCTION_CAMPAIGN"
- "AUCTION_ADGROUP"
- "AUCTION_AD"
TikTok only (required there): 1-4 comma-separated TikTok dimensions (e.g. country_code, campaign_id, stat_time_day).
TikTok only (required there): comma-separated TikTok metrics (e.g. reach,impressions,frequency,spend).
TikTok only: page number.
1 <= value1TikTok only: rows per page.
1 <= value <= 1000100Alias of adAccountId, kept for existing callers
Google only: cursor from paging.nextPageToken of the previous page.
Row granularity
Value in
- "ad"
- "adset"
- "campaign"
- "account"
Comma-separated Graph insights fields (e.g. spend,impressions,frequency,website_purchase_roas). Omitted = Meta's default set.
Meta only: comma-separated Graph breakdowns (e.g. age,gender or publisher_platform). Returns 400 on TikTok (add the breakdown to dimensions with reportType=AUDIENCE, e.g. dimensions=campaign_id,placement) and on Google (select segments.* in the query).
Comma-separated Graph action breakdowns; segments the actions[] arrays in each row. Pass none to clear Meta's default action_type breakdown, required to combine some non-action breakdowns such as instagram_ads_follow_type (otherwise Meta returns a (#100) invalid-combination error).
Comma-separated Meta attribution windows. Action values are returned keyed per window.
When actions are counted: impression, conversion or mixed.
Use the ad sets' own attribution settings for action counting.
JSON array of filter objects: [{"field", "operator", "value"}]. Applied server-side by Meta or TikTok (TikTok fields e.g. campaign_ids, adgroup_ids, ad_ids).
Meta date_preset (e.g. last_7d, last_30d, this_month). Mutually exclusive with fromDate/toDate.
Start of range (YYYY-MM-DD); requires toDate. Required on TikTok.
dateEnd of range (YYYY-MM-DD); requires fromDate.
dateDays per row (1-90), monthly, or all_days.
Rows per page
1 <= value <= 50025Cursor from paging.after of the previous page.
Response Body
application/json
application/json
application/json
application/json
application/json
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.adinsights.queryAdInsights({ query: { accountId: 'account_abc123', },});console.log(data);{ "objectId": "string", "adAccountId": "string", "customerId": "string", "fieldMask": "string", "data": [ {} ], "paging": { "after": "string", "nextPageToken": "string", "page": 0, "pageSize": 0, "totalRows": 0, "totalPages": 0 }}Generate keyword ideas
Suggests new keywords from seed keywords or a website using Google Keyword Planner, with search volume, competition and bid estimates. Google Ads only. Runs Keyword Planner's generateKeywordIdeas from seed keywords, a seed URL, or both, returning idea rows verbatim (avgMonthlySearches, competition, competitionIndex, top-of-page bid micros, monthlySearchVolumes). Counters are int64s encoded as strings; bid values are micros of the account currency. Omitting `countries` targets worldwide.
List account conversion goals
Lists a Google Ads account's default conversion goals, which ones are used for bidding, and the conversion actions in each. Google Ads account-default conversion goals (CustomerConversionGoal), one per category and origin, with `biddable` (whether the goal is used for bidding and reported in the Conversions column) and the conversion actions that belong to it, each flagged `primaryForGoal` (primary) or not (secondary). Reads are cached for 10 minutes; when the shared Google quota is exhausted the last successful result is served with `stale: true`.