Ads

Targeting

Target ads by location, age, interests, keywords, job titles or subreddits, look up each network's ids with one search endpoint and estimate reach first.

Targeting tells a network who should see an ad. Pozy uses one set of field names across networks, then translates them into each network's own targeting spec. Portable fields such as countries, ageMin, ageMax, gender and languages work everywhere. The rest only mean something on the network they were looked up for, and a field a network cannot honor is rejected with a 400 that names it.

#Where targeting goes

Call Shape
POST /v1/ads/create Flat fields at the top level (Meta, TikTok, Pinterest, X, Reddit), or a nested targeting object (LinkedIn, Google accepts both)
POST /v1/ads/boost Inside targeting
POST /v1/ads/messaging, POST /v1/ads/call Flat fields, like create
PUT /v1/ads/{adId} targeting updates the ad's ad set or campaign where the network allows it
PUT /v1/ads/campaigns/{campaignId}/targeting Google campaign-level devices, locations and languages
POST /v1/ads/targeting/reach-estimate Inside spec

#Look up ids

Cities, regions, interests, job titles and subreddits are ids that belong to each network. Find them with GET /v1/ads/targeting/search, using the accountId of the ad connection you will create the ad on.

curl -G https://api.pozy.ai/v1/ads/targeting/search \
  -H "Authorization: Bearer $POZY_API_KEY" \
  --data-urlencode "accountId=66b2e19d8c3f5a7e9d0b1c2d" \
  --data-urlencode "q=Amsterdam" \
  --data-urlencode "dimension=geo" \
  --data-urlencode "geoType=city" \
  --data-urlencode "countryCode=NL"
Response
{
  "results": [
    { "id": "2759794", "name": "Amsterdam", "type": "city", "path": ["Netherlands", "North Holland", "Amsterdam"], "audienceSize": null }
  ]
}

Send a geo result's id as key in cities, regions, zips or metros. A country result's id is the ISO code for countries. Interest and behavior results go in interests and behaviors as { id, name }.

dimension Meta Google TikTok LinkedIn X Reddit
geo Yes Yes Yes Yes Yes Yes
interest Yes Yes (affinity and in-market) Yes Yes Yes Yes
behavior Yes – Yes Yes – –
language – Yes – – – –
income Yes Yes (top_10 only) – – – –
workPosition, workEmployer, workIndustry Yes – – – – –
industry, jobFunction, seniority, companySize, skill – – – Yes – –
community, conversationKeyword – – – – – Yes

geoType narrows geo searches to country, region, city (the default), subcity, neighborhood, place, zip, metro_area or geo_market. Google and LinkedIn ignore it and return every level, so filter on each result's type. GET /v1/ads/targeting/browse walks Meta's targeting category tree (by type and parentNodeId) instead of searching it. dimension defaults to interest. A dimension the network does not support returns 400 or 404.

#Estimate reach first

POST /v1/ads/targeting/reach-estimate returns an audience size range before you create anything:

Request
{
  "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
  "adAccountId": "act_1234567890",
  "spec": { "countries": ["NL"], "ageMin": 25, "ageMax": 54, "interests": [{ "id": "6003107902433", "name": "Interior design" }] }
}
Response
{ "available": true, "lower": 412000, "upper": 585000, "estimateReady": true }

estimateReady: false means the network is still computing, which happens with brand-new audiences: retry shortly. Networks without an estimate return available: false. On LinkedIn, bid pricing and supply forecasts add bid ranges and projected delivery.

#Meta

Field Values
countries, countryGroups ISO codes, or groups such as eea or north_america. Defaults to ["US"] only when no geo field is sent.
cities { key, radius, distance_unit }. Meta's minimum radius is about 17 km (10 miles); smaller resolves to an empty audience.
regions, zips, metros { key } from the search, for example US:94304 or DMA:807
customLocations { latitude, longitude, radius, distanceUnit }
excludedLocations Countries, regions, cities, ZIPs, places, neighborhoods, custom locations
ageMin, ageMax 13 to 65
gender all, male, female
interests, behaviors { id, name }
workPositions, workEmployers, workIndustries { id, name }
incomeTier top_5, top_10, top_10_25, top_25_50 (household income by ZIP)
languages en targets every variant, en_GB one
userOs, userDevice For example iOS_ver_14.0_and_above, iPhone
audienceInclude, audienceExclude Audience ids (Audiences)
placements Manual placements. Omit for automatic placements.
savedTargetingId A saved targeting audience as the base, with inline fields on top
rawTargeting A Meta-native spec for anything the flat fields do not cover, such as layered flexible_spec
advantageAudience 0 keeps targeting strict, 1 lets Meta expand
Locations overlap

Do not send a city together with the country that contains it. Meta rejects the ad. Drop the country, or use a different one.

Housing, employment and credit ads (specialAdCategories) cannot use income or ZIP targeting. EU delivery needs dsaBeneficiary and dsaPayor.

#Google

Field Values
countries ISO codes. Search and Display default to US with no geo; Performance Max and Demand Gen run worldwide.
regions, cities, zips, metros { key }, Google's geo target ids
customLocations A pin with radius (Google has no city radius)
excludedLocations Countries, regions, cities, ZIPs
languages ISO 639-1 codes plus variants such as zh_CN
ageMin, ageMax, gender Search and Display only, 18 and over
incomeTier top_10 only
interests Affinity and in-market segments, Search and Display
audienceInclude, audienceExclude User list ids, such as Customer Match lists
keywords, negativeKeywords Search only, see Google Ads

locationTargetingType sets whether locations reach people physically there (presence) or also people interested in them (presence_or_interest, Google's default). Performance Max and Demand Gen take geo and language only. On a running campaign, PUT /v1/ads/campaigns/{campaignId}/targeting replaces devices (MOBILE, DESKTOP, TABLET, CONNECTED_TV, each with an optional bid modifier), locations, excludedLocations and languages.

#TikTok

Field Values
countries ISO codes. Required on boosts.
regions, cities, zips, metros Create only
ageMin, ageMax, gender, languages zh_TW targets traditional Chinese
interests From the interest search
behaviors video:<id> or creator:<id>. Restricts delivery to the TikTok placement.
incomeTier As on Meta
audienceInclude, audienceExclude Processed custom audiences

PUT /v1/ads/{adId} with targeting is a partial update; fields you leave out keep their value, except that a new location replaces both location and ZIP targeting.

#LinkedIn

Field Values
countries, regions ISO codes or urn:li:geo:*. At least one location; none means the United States.
industries, seniorities, jobFunctions, jobTitles, skills Id fragments or full URNs
companySizes A to I staff-count ranges
interests, behaviors URNs from the search
audienceInclude, audienceExclude Matched audience segment ids
ageMin, ageMax, gender, languages Rounded to LinkedIn's buckets
excludedLocations.countries ISO codes

jobTitles cannot be combined with seniorities or jobFunctions. Cities, ZIP codes, radius and income return 400. Updates through PUT /v1/ads/{adId} merge facet by facet; send a facet empty to remove it.

#Pinterest

countries, regions, metros, zips, ageMin, ageMax, gender, languages, interests (from GET /v1/ads/interests) and customer list audiences. regions and zips cannot be combined. Targeting cannot change after create: recreate the ad.

#X

countries, regions, metros, cities, zips, interests, Tailored Audiences, gender and languages. Age rounds out to X's fixed ranges (starting at 13, 18, 21, 25, 35 or 50 and ending at 24, 34, 49 or 54, or open-ended), so ageMin: 20, ageMax: 40 targets 18 to 49. Income, custom locations and behaviors are rejected. Targeting cannot change after create.

#Reddit

Field Values
countries, regions, metros, cities, zips No location means US
excludedLocations Countries, regions, cities and ZIPs
gender, languages
targeting.interests From the interest search
targeting.communities, targeting.excludedCommunities Subreddit names, with or without r/
targeting.conversationKeywords, targeting.excludedConversationKeywords Free text
audienceInclude, audienceExclude Custom audiences built in Reddit Ads Manager

Age, income and radius are not available. Targeting can be changed after launch with PUT /v1/ads/{adId}.

#ChatGPT

ChatGPT ads target by country only.

#Endpoints

Endpoint What it does
GET /v1/ads/interests Search targeting interests
GET /v1/ads/targeting/search Search targeting options
GET /v1/ads/targeting/browse Browse targeting categories
POST /v1/ads/targeting/reach-estimate Estimate audience reach
POST /v1/ads/targeting/bid-pricing Suggested bid and budget bounds
POST /v1/ads/targeting/supply-forecast Forecast ad delivery