Zernio
Zernio
API Reference

Targeting

Search targeting optionsGETSuggested bid and budget boundsPOSTForecast ad deliveryPOSTBrowse targeting categoriesGETEstimate audience reachPOST
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
Targeting

Browse targeting categories

The whole Meta detailed-targeting category tree of one ad account (Meta's GET /act_{ad_account_id}/targetingbrowse), as one flat list you can render as a tree. Use it to show what can be targeted without a keyword; use GET /v1/ads/targeting/search to find an entry by name.

Every node is one of two kinds:

  • Selectable entity (selectable: true): an interest, behavior or demographic Meta gives an id. id plus type is what a targeting spec takes. interests, behaviors and industries ids go in TargetingSpec.interests, behaviors and workIndustries on POST /v1/ads/create; every other type goes in rawTargeting.flexible_spec under its type as the key. life_events, family_statuses and income take objects ({ "flexible_spec": [{ "life_events": [{ "id": "6017476616183" }] }] }), while education_statuses and relationship_statuses take the bare number ({ "flexible_spec": [{ "education_statuses": [3] }] }): Meta answers an object there with a 500.
  • Organizational node (selectable: false, id: null): a category such as Demographics > Financial > Income that only groups other nodes and cannot be targeted. A few carry a type and have no children (Schools, Employers, Job titles, Fields of study, Undergrad years): those are open-ended categories Meta only exposes through search (dimension=workEmployer / workPosition on the search endpoint).

nodeId identifies a node within this response and parentNodeId points at its parent (null for the three roots Demographics, Interests, Behaviors). A selectable node's nodeId is {type}:{id}, because Meta reuses small ids across types (education status 3 and relationship status 3 are different entities). An organizational node's nodeId is its full path joined with >. Labels are kept exactly as Meta sends them, including stray leading or trailing spaces, because Meta has sibling nodes that differ only by whitespace.

The interests branch is Meta's curated browse list (a few hundred entries), not every interest Meta can target: search finds the long tail.

No pagination. Meta returns the whole catalog in one response (about 770 nodes) and ignores limit, so there is no cursor. Narrow it with type, parentNodeId and selectable instead; they are applied by Zernio. The catalog is cached for an hour per ad account and connection.


PlatformsMeta
GET
/v1/ads/targeting/browse

Authorization

bearerAuth
AuthorizationBearer <token>

API key authentication: send your Zernio API key in the Authorization header, prefixed with Bearer.

In: header

Query Parameters

accountId*string

A connected Meta account (metaads, facebook or instagram). Any other ad platform returns 501 platform_not_supported.

adAccountId*string

The Meta ad account to browse as, in the form "act_".

Match^act_\d+$
type?string

Only the nodes of this Meta type (e.g. interests, behaviors, life_events, income), plus the organizational nodes leading to them. A type that is not in the catalog returns 400.

parentNodeId?string

Only the descendants (every depth) of this organizational node, e.g. Demographics > Financial. A nodeId that is not an organizational node of the catalog returns 400.

selectable?boolean

true for selectable entities only, false for organizational nodes only.

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.adtargeting.browseAdTargeting({  query: {    accountId: 'account_abc123',    adAccountId: 'adaccount_abc123',  },});console.log(data);
{  "adAccountId": "act_1234567890",  "nodes": [    {      "nodeId": "Demographics > Financial > Income",      "parentNodeId": "Demographics > Financial",      "id": null,      "name": "Income",      "type": null,      "path": [        "Demographics",        "Financial"      ],      "selectable": false    },    {      "nodeId": "income:6107813551783",      "parentNodeId": "Demographics > Financial > Income",      "id": "6107813551783",      "name": "Household income: top 10% of ZIP codes (US)",      "type": "income",      "path": [        "Demographics",        "Financial",        "Income"      ],      "selectable": true,      "description": "People who live in the top 10% of US ZIP codes by average household income based on publicly available information",      "audienceSizeLowerBound": 31201895,      "audienceSizeUpperBound": 36693429    }  ]}
Was this page helpful?

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`.

Estimate audience reach

Returns a normalized pre-flight audience-size estimate for a targeting spec, before any campaign is created. Backed by each platform's native reach API (Meta `delivery_estimate`, LinkedIn `audienceCounts`, X `audience_summary`, Pinterest `audience_sizing`). Platforms without a usable pre-flight reach API (Google Search/Display, TikTok) return `available: false` with no bounds, so clients can hide or grey out the estimate rather than treat the absence as an error.