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.
Authorization
bearerAuth API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
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.generateKeywordIdeas({ body: { accountId: 'account_abc123', },});console.log(data);{ "customerId": "string", "data": [ {} ], "aggregateMetricResults": {}, "paging": { "nextPageToken": "string" }}Get historical keyword metrics
Gets historical search volume, competition and bid ranges for up to 1,000 keywords from Google Keyword Planner. Google Ads only. Runs Keyword Planner's generateKeywordHistoricalMetrics for up to 1,000 exact keywords: historical search volume, competition and top-of-page bid ranges, plus averageCpcMicros when includeAverageCpc is set. Rows come back verbatim; counters are int64s encoded as strings, bid/CPC values are micros of the account currency.
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.