Suggested bid and budget bounds
LinkedIn-only. Returns the suggested bid and bid limits for a targeting
spec, plus the daily-budget bounds LinkedIn will accept. Use it before
creating a campaign to pick a bid inside the allowed range and warn the
user if their daily budget is below the minimum. Wraps LinkedIn's
adBudgetPricing finder.
Non-LinkedIn accounts return available: false so clients can hide the
pricing UI without treating it as a failure.
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
import Zernio from '@zernio/node';const zernio = new Zernio({ apiKey: process.env.ZERNIO_API_KEY });const { data } = await zernio.adtargeting.getLinkedInBidPricing({ body: { accountId: 'account_abc123', adAccountId: 'adaccount_abc123', spec: { userOs: [ 'string', ], userDevice: [ 'string', ], countries: [ 'string', ], }, },});console.log(data);{ "available": true, "pricing": { "bidLimits": { "min": { "amount": "string", "currencyCode": "string" }, "max": { "amount": "string", "currencyCode": "string" } }, "suggestedBid": { "min": { "amount": "string", "currencyCode": "string" }, "default": { "amount": "string", "currencyCode": "string" }, "max": { "amount": "string", "currencyCode": "string" } }, "dailyBudgetLimits": { "min": { "amount": "string", "currencyCode": "string" }, "default": { "amount": "string", "currencyCode": "string" }, "max": { "amount": "string", "currencyCode": "string" } } }}Search targeting options
Finds targeting options by name, such as locations, interests or behaviors, and returns the ids to use in ad targeting. Resolve a human-readable query into the platform's opaque targeting ids used in the `TargetingSpec` (`countries`/`regions`/`cities`/`zips`/`metros` geo keys, and `interests`/`behaviors` entity ids) on `POST /v1/ads/create`, `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences. The `dimension` param selects what is searched: - `geo`: locations, further scoped by `geoType` - `interest` - `interestSuggestion`: Meta only. Interests related to the interest names in `q`, from Meta's interest suggestions. `q` lists interest names, case sensitive, names and not ids: either comma-separated (`NBA,Michael Jordan`) or, for names that contain a comma, a JSON array of strings (`["Earth, Wind & Fire","Yoga"]`, URL-encoded). A `q` starting with `[` is always read as JSON. A `q` with no name or malformed JSON returns 400 naming `q`. Meta also suggests behaviors and demographics; Zernio keeps only interests, so every id goes in `TargetingSpec.interests`, like `interest` results. Zernio classifies them with a Meta call pinned to `en_US` (ids whose `path` starts with `Interests`). Without `locale` results are in English; with another `locale`, a second call in that locale returns the same interests with localized names and `path`. Zernio asks Meta for three times `limit` (at most 100) before filtering, so fewer than `limit` results can come back. Meta weights the first name heavily: a multi-name `q` mostly returns suggestions for the first one - `behavior`: Meta, TikTok and LinkedIn, matched by name; ids feed `TargetingSpec.behaviors`. Meta: its fixed behaviors catalog (e.g. `Small business owners`, `Frequent Travelers`). TikTok: video and creator interaction categories (e.g. `Software & Apps`), with ids like `video:1913101` or `creator:24001` and `path` starting with `Video interactions` or `Creator interactions` (hashtags are their own `hashtag` dimension). LinkedIn: member behaviors (e.g. `Frequent Travelers`, `Job Seekers`, `Recently Promoted`), ids like `urn:li:memberBehavior:9`. Google has no separate behavior catalog: its in-market and affinity segments come back from `interest`, and X removed behavior targeting from its Ads API - `interestKeyword`: TikTok only. The "Additional interests" of TikTok Ads Manager (e.g. `folk` returns `Folk Music`), from TikTok's keyword recommendations for the seed `q`. Ids look like `keyword:123456` and go in `TargetingSpec.interests`, next to interest categories. Only keywords TikTok lets an ad group target come back (`status` `EFFECTIVE`). TikTok returns no audience size - `hashtag`: TikTok only. Hashtags recommended for the seed `q`, to target people who viewed videos with them. Ids look like `hashtag:123456` and go in `TargetingSpec.behaviors`. Only hashtags TikTok reports `ONLINE` come back. Spaces in `q` are removed first, because TikTok recommends no hashtags for a multi-word seed (`acoustic guitar` searches `acousticguitar`) - `income`: the household-income tiers the platform can target (Meta, TikTok, Google). The id is the normalized tier (`top_5`, `top_10`, `top_10_25`, `top_25_50`) to pass as `TargetingSpec.incomeTier`, never a platform segment id. Meta's tiers are US-only ZIP-code percentiles (label and `audienceSize` come live from Meta), TikTok expresses all four and Google only `top_10`. `q` is matched against the label, so `top` or `income` lists every tier - `language`: Google-only - `workPosition`, `workEmployer`, `workIndustry`: the Meta-only work demographics, whose ids feed `TargetingSpec.workPositions`/`workEmployers`/`workIndustries` - `industry`, `jobFunction`, `seniority`, `companySize`, `skill`: the LinkedIn-only B2B facets, whose URNs feed `TargetingSpec.industries`/`jobFunctions`/`seniorities`/`companySizes`/`skills` - `community`: Reddit only. Subreddits matching `q`; the id is the subreddit name for `TargetingSpec.communities` / `excludedCommunities`, `platformId` Reddit's own id and `audienceSize` its subscriber count when Reddit reports it - `conversationKeyword`: Reddit only. Reddit's keyword suggestions for the seed `q`; the id is the keyword for `TargetingSpec.conversationKeywords` / `excludedConversationKeywords` Availability of each dimension varies by platform. A dimension a platform cannot search returns a 400 naming `dimension`; it never falls back to another dimension, and every result's `type` is the requested dimension (or the geo level for `geo`). TikTok `interest` searches TikTok's interest category catalog (about 700 categories over four levels, `path` holds the parent categories), matched by name in Zernio. The ids are what `TargetingSpec.interests` sends to TikTok as `interest_category_ids`. For `interestKeyword` and `hashtag`, a `q` made only of prefixed ids (`keyword:101,keyword:102` or `hashtag:201`) looks those ids up instead of searching, unavailable ones included with their `status` (`INEFFECTIVE` or `OFFLINE`), so ids read back from an ad group (`interest_keyword_ids`, `actions` in `nativeSettings`) resolve to names. An `interestKeyword` lookup takes at most 50 ids (more returns 400 naming `q`). Work industries are a fixed ~30-entry Meta catalog with no server-side query, so `workIndustry` matching, ranking and `limit` happen in Zernio. `language` is likewise a fixed, checked-in table of Google's targetable `language_constant` rows (id, ISO code, name) matched by name or code, capped at 20, with no network call; its ids feed `TargetingSpec.languages`. Results are normalized across platforms into a single shape, so the same client code consumes Meta, TikTok, LinkedIn, X, Pinterest, Google and Reddit results. TikTok geo searches return every matching level in one list (`type` is `country`, `region`, `city`, `district`, or `metro` for DMA areas), and `geoType` is not applied. Results are scoped to the advertiser's targetable markets (pass `adAccountId` when the connection holds several advertisers). A two-letter `q` also matches a country by ISO code (`q=GB` returns the United Kingdom first). A `country` result's id is its ISO 3166-1 alpha-2 code, for `targeting.countries`; every other id is TikTok's numeric location id, usable in `regions`/`cities`/`metros` keys on `POST /v1/ads/create`. LinkedIn geo searches also return every matching level in one list, and neither `geoType` nor `countryCode` is applied: LinkedIn's typeahead only returns a name and a URN per result, with no level or country field to filter on. A result whose URN is a country Zernio holds a code for has `type: country` and its ISO 3166-1 alpha-2 code as the id, for `targeting.countries`. Every other result has `type: region` and keeps its `urn:li:geo:*` URN as the id, usable as a `regions[].key` on `POST /v1/ads/create`, `POST /v1/ads/boost` and `POST /v1/ads/targeting/reach-estimate` (LinkedIn puts countries and regions in the same `locations` facet, so both target the same way). LinkedIn B2B searches (`industry`, `jobFunction`, `seniority`, `companySize`, `skill`) return the full URN to pass straight back, so no URN id fragment has to be assembled by hand: `urn:li:industry:4`, `urn:li:function:8`, `urn:li:seniority:6`, `urn:li:staffCountRange:(51,200)`, `urn:li:skill:1346`. Only `industry` and `skill` are server-side name searches (LinkedIn's typeahead finder). LinkedIn exposes no typeahead for job functions, seniorities and company sizes, so Zernio fetches each whole table (26, 10 and 9 entries), caches it, and does the matching, ranking and `limit` cutoff itself. Those three never carry `audienceSize`, and `countryCode` and `geoType` are not applied to any of the four. Google geo searches resolve against Google's geoTargetConstants and return every matching level in one list; `geoType` is not applied (Google's `target_type` is an open taxonomy that does not map one-to-one onto the `geoType` enum), so filter client-side on the returned `type` (`country`, `region`, `city`, `zip`, `metro`, or the lowercased Google target type for rarer levels). `countryCode` scopes the search to one country. A `country` result's id is its ISO 3166-1 alpha-2 code, for `targeting.countries`; every other id is Google's numeric criterion id, usable as a `regions`/`cities`/`zips`/`metros` `key` on `POST /v1/ads/create`. Google city radius is not supported (pass a `customLocations` lat/lng pin for a radius); country targeting also accepts plain ISO codes via `countries` with no search call. Pinterest resolves against three whole-catalog endpoints (interests, locations, regions) with no server-side query or pagination, so matching, ranking and the `limit` cutoff all happen in Zernio; the catalog is independent of any ad account and results never carry `audienceSize`. Names come back localized to the connected Pinterest account's language (there is no way to force a locale), so match against whatever language that account returns. `geoType` routes to a different Pinterest catalog: - `country` and `metro_area` read the locations catalog (`type` is `country` or `metro`) - `region` reads the regions catalog (`type` is `region`, its id a `regions[].key` on `POST /v1/ads/create`) - `all` and the default `city` merge both catalogs with honest per-entry `type`s, since Pinterest has no city-level catalog and `city` is an alias for `all`, not a literal city search - `zip`, `subcity`, `neighborhood`, `place` and `geo_market` return a 400: Pinterest exposes no postal-code catalog, pass postal codes directly as `targeting.zips: [{ key }]` on `POST /v1/ads/create` Reddit (`redditads` connection) searches `geo`, `interest`, `community` and `conversationKeyword`; any other dimension returns 400. Its geo search honours `geoType` `city` (the default, a server-side city search), `zip` (`q` is the postal code), `country`, `region` and `metro_area` (matched in Zernio against Reddit's geolocation catalog) and `all`; other values return 400. `countryCode` scopes every geo search. Each result's id is Reddit's geolocation id, usable as a `regions`/`metros`/`cities`/`zips` `key` (country ids go in `countries`). `interest` matches Reddit's interest catalog in Zernio, with the category as `path`. For geo queries, `q` should contain only the locality name (e.g. `"Amsterdam"`, not `"Amsterdam, NL"`). Use `countryCode` to disambiguate. Meta language: Meta matches `q` against names in one language and returns names and `path` in that language. Pass `locale` (e.g. `pl_PL`) to choose it. Without `locale`, the `behavior` and `workIndustry` catalogs and `interestSuggestion` are in `en_US`, and `interest`, `geo`, `workPosition` and `workEmployer` follow the language of the Facebook user who connected the account (so a Russian-language Facebook user gets Russian paths, and Polish names need `locale=pl_PL`). A non-English `behavior` or `workIndustry` query without `locale` never matches, so pass the locale of the names you search. Meta's `interest` search matches its own interest names and has no fuzzy or synonym mode, so a phrase Meta does not use as an interest name (e.g. `dental implants`) can return nothing while a shorter word (`dentistry`) does. If Meta returns an empty `behavior`, `workIndustry` or `income` catalog the request fails with a 502 `platform_api_error` instead of an empty `results` list.
Forecast ad delivery
LinkedIn-only. Forecasted impressions, clicks, spend and ~20 other metrics for a targeting spec over a time range. Wraps LinkedIn's `adSupplyForecasts` finder. Each returned series carries a `metricType` (IMPRESSION, CLICK, SPENDING, MAX_POTENTIAL_BUDGET, COST_PER_MILLION_IMPRESSIONS, ...) and a `granularity` (DAILY, SEVEN_DAY, THIRTY_DAY, CUSTOM). LinkedIn caps the daily spending forecast at 1.2x the daily budget and returns 0 once the total budget is exhausted. Non-LinkedIn accounts return `available: false`.