Targeting
Interest, demographic, and behavior targeting
Targeting
Use /v1/ads/interests?platform=metaads&q=devops to search interest IDs, and /v1/ads/targeting/search?type=city&q=Amsterdam&countryCode=NL to look up city / region keys.
| Field | Type | Description |
|---|---|---|
ageMin | number | Minimum age (13-65) |
ageMax | number | Maximum age (13-65) |
countries | string[] | ISO 3166-1 alpha-2 country codes. Defaults to ["US"] when no cities or regions are provided. |
cities | object[] | City-level targeting. Each entry: { key, radius?, distance_unit? } where key is from /v1/ads/targeting/search, and radius + distance_unit ("kilometer" or "mile") must be set together. |
regions | object[] | Region/state-level targeting. Each entry: { key } from /v1/ads/targeting/search?type=region. |
interests | object[] | { id, name } from /v1/ads/interests |
gender | string | "all", "male", or "female" (default "all") |
On /v1/ads/create, targeting fields are flat at the top level (ageMin, ageMax, countries, cities, regions, interests). On /v1/ads/boost, they live inside a targeting: { ... } object that's passed through to Meta as-is.
Looking up city / region keys
Meta's cities and regions use opaque IDs that aren't derivable from the name. Use the targeting search helper to resolve them:
// Find Meta's key for Amsterdam in NL
const { results } = await zernio.ads.searchAdTargetingLocations({
accountId: 'FB_ACCOUNT_ID',
q: 'Amsterdam',
type: 'city',
countryCode: 'NL',
});
// results[0].key → "2759794"
// Use the key on /v1/ads/create
await zernio.ads.createStandaloneAd({ body: {
accountId: 'FB_ACCOUNT_ID',
adAccountId: 'act_1234567890',
name: 'Amsterdam launch',
goal: 'traffic',
budgetAmount: 20,
budgetType: 'lifetime',
endDate: '2026-05-15T00:00:00Z',
headline: 'Hello Amsterdam',
body: 'Try us this week.',
linkUrl: 'https://example.com',
imageUrl: 'https://cdn.example.com/promo.jpg',
callToAction: 'LEARN_MORE',
cities: [{ key: '2759794', radius: 25, distance_unit: 'kilometer' }],
dsaBeneficiary: 'Acme BV',
dsaPayor: 'Acme BV',
}});results = client.ads.search_ad_targeting_locations(
account_id="FB_ACCOUNT_ID",
q="Amsterdam",
type="city",
country_code="NL",
)["results"]
# results[0]["key"] → "2759794"
client.ads.create_standalone_ad(
account_id="FB_ACCOUNT_ID",
ad_account_id="act_1234567890",
name="Amsterdam launch",
goal="traffic",
budget_amount=20,
budget_type="lifetime",
end_date="2026-05-15T00:00:00Z",
headline="Hello Amsterdam",
body="Try us this week.",
link_url="https://example.com",
image_url="https://cdn.example.com/promo.jpg",
call_to_action="LEARN_MORE",
cities=[{"key": "2759794", "radius": 25, "distance_unit": "kilometer"}],
dsa_beneficiary="Acme BV",
dsa_payor="Acme BV",
)# 1. Look up the city key
curl "https://zernio.com/api/v1/ads/targeting/search?accountId=FB_ACCOUNT_ID&q=Amsterdam&type=city&countryCode=NL" \
-H "Authorization: Bearer YOUR_API_KEY"
# 2. Use the key on /v1/ads/create
curl -X POST "https://zernio.com/api/v1/ads/create" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accountId": "FB_ACCOUNT_ID",
"adAccountId": "act_1234567890",
"name": "Amsterdam launch",
"goal": "traffic",
"budgetAmount": 20,
"budgetType": "lifetime",
"endDate": "2026-05-15T00:00:00Z",
"headline": "Hello Amsterdam",
"body": "Try us this week.",
"linkUrl": "https://example.com",
"imageUrl": "https://cdn.example.com/promo.jpg",
"callToAction": "LEARN_MORE",
"cities": [{ "key": "2759794", "radius": 25, "distance_unit": "kilometer" }],
"dsaBeneficiary": "Acme BV",
"dsaPayor": "Acme BV"
}'type accepts city, region, country, subcity, neighborhood, zip, metro_area, geo_market. Pass countryCode to disambiguate when the same name exists in multiple countries (e.g. there are several "Eindhoven"s globally).
Don't combine cities with the same countries, Meta returns a "locations overlap" error because the city is already inside the country boundary. Either drop the country, or scope countries to a different country than the cities you're targeting.