Targeting Helpers
Complete reference for geographic, demographic, audience, schedule, and display targeting helpers.
All targeting helpers are imported from @upspawn/ads. Use targeting() to compose multiple rules into a single Targeting object accepted by campaigns.
targeting(...rules)
Compose multiple targeting rules into a single Targeting object. Pass any combination of the helpers below.
function targeting(...rules: TargetingRule[]): Targetingimport { targeting, geo, languages, weekdays, hours, device, presence } from '@upspawn/ads'
const t = targeting(
geo('US', 'CA'),
languages('en'),
weekdays(),
hours(9, 17),
device('mobile', -0.5),
presence('presence'),
)Rules are additive. Multiple rules of different types are all applied. Multiple device() rules each apply to their respective device.
Geographic
geo(...countries)
Target specific countries by ISO country code. Optionally pass per-country bid adjustments.
function geo(
...args: [...CountryCode[]] | [...CountryCode[], { bidAdjustments: Record<string, number> }]
): GeoTargetimport { geo } from '@upspawn/ads'
geo('US') // single country
geo('US', 'CA', 'GB') // multiple countries
geo('US', 'DE', { bidAdjustments: { US: 0.2, DE: -0.1 } }) // with bid adjustmentsThrows if no country codes are provided.
regions(...regionIds)
Target specific regions (states, provinces) by name or ID.
function regions(...regionIds: string[]): RegionTargetimport { regions } from '@upspawn/ads'
regions('California', 'New York', 'Texas')cities(...cityNames)
Target specific cities by name.
function cities(...cityNames: string[]): CityTargetimport { cities } from '@upspawn/ads'
cities('Berlin', 'Munich', 'Hamburg')radius(lat, lng, radiusKm)
Target a circular area around a geographic coordinate.
function radius(lat: number, lng: number, radiusKm: number): RadiusTargetimport { radius } from '@upspawn/ads'
radius(52.52, 13.405, 50) // 50 km around Berlin
radius(40.71, -74.01, 25) // 25 km around New York CityThrows if radiusKm is not positive.
presence(mode)
Control whether targeting applies to people physically in the location or also those with interest in it.
function presence(mode: 'presence' | 'presence-or-interest'): PresenceTargetimport { presence } from '@upspawn/ads'
presence('presence') // only people physically in the targeted location
presence('presence-or-interest') // also people who search for or show interest in the locationLanguage
languages(...langs)
Target by ISO language code.
function languages(...langs: LanguageCode[]): LanguageTargetimport { languages } from '@upspawn/ads'
languages('en')
languages('en', 'de', 'fr')Throws if no language codes are provided.
Schedule
weekdays()
Restrict delivery to Monday through Friday (all hours).
function weekdays(): ScheduleTargetimport { weekdays } from '@upspawn/ads'
weekdays()
// { type: 'schedule', days: ['mon', 'tue', 'wed', 'thu', 'fri'] }hours(startHour, endHour)
Restrict delivery to a specific hour range within a day.
function hours(startHour: number, endHour: number): ScheduleTargetstartHour: 0–23 (inclusive)endHour: 1–24 (inclusive), must be greater thanstartHour
import { hours } from '@upspawn/ads'
hours(9, 17) // 9am–5pm
hours(0, 8) // midnight–8amCombine with weekdays() to restrict to business hours Monday–Friday:
targeting(weekdays(), hours(9, 17))scheduleBid(day, startHour, endHour, bidAdjustment)
Apply a bid adjustment for a specific day and hour range.
function scheduleBid(
day: Day,
startHour: number,
endHour: number,
bidAdjustment: number,
): ScheduleBidTargetday:'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun'bidAdjustment: −1.0 to 9.0.-1.0excludes the slot,0.0= no change,0.3= +30%
import { scheduleBid } from '@upspawn/ads'
scheduleBid('mon', 9, 17, 0.2) // +20% on Monday 9am–5pm
scheduleBid('sat', 0, 24, -0.3) // −30% on SaturdaysDevice
device(deviceType, bidAdjustment)
Apply a bid adjustment for a specific device type.
function device(
deviceType: 'mobile' | 'desktop' | 'tablet',
bidAdjustment: number,
): DeviceTargetbidAdjustment: −1.0 to 9.0-1.0= exclude this device entirely (−100%)0.0= no change (default)0.3= +30% bid increase-0.5= −50% bid reduction
import { device } from '@upspawn/ads'
device('mobile', -1.0) // exclude mobile entirely
device('tablet', -0.5) // reduce tablet bids by 50%
device('desktop', 0.2) // increase desktop bids by 20%Add multiple device() rules to target all three types:
targeting(
geo('US'),
device('mobile', -1.0),
device('tablet', -0.5),
)Demographics
demographics(opts)
Target specific demographic segments. All fields are optional.
function demographics(opts: {
ageRanges?: AgeRange[]
genders?: Gender[]
incomes?: IncomeRange[]
parentalStatuses?: ParentalStatus[]
}): DemographicTargetValid values:
| Field | Valid values |
|---|---|
ageRanges | '18-24', '25-34', '35-44', '45-54', '55-64', '65+', 'undetermined' |
genders | 'male', 'female', 'undetermined' |
incomes | 'top-10', 'top-10-20', 'top-20-30', 'top-30-40', 'top-40-50', 'lower-50', 'undetermined' |
parentalStatuses | 'parent', 'not-parent', 'undetermined' |
import { demographics } from '@upspawn/ads'
demographics({
ageRanges: ['25-34', '35-44'],
genders: ['male'],
})
demographics({
incomes: ['top-10', 'top-10-20'],
parentalStatuses: ['parent'],
})Audiences (Google)
Audience helpers create AudienceRef objects that are passed to audiences() or audienceTargeting().
audiences(...refs)
Add audiences in observation mode — ads still show to everyone, but you collect performance data per audience and can apply bid adjustments.
function audiences(...refs: AudienceRef[]): AudienceTargetimport { audiences, remarketing, inMarket } from '@upspawn/ads'
audiences(
remarketing('123456789', { bidAdjustment: 0.5 }),
inMarket('80432', { name: 'Business Software' }),
)audienceTargeting(...refs)
Add audiences in targeting mode — ads are restricted to only these audiences.
function audienceTargeting(...refs: AudienceRef[]): AudienceTargetimport { audienceTargeting, remarketing } from '@upspawn/ads'
audienceTargeting(
remarketing('123456789', { name: 'Cart Abandoners' }),
)remarketing(listId, options?)
Reference a remarketing list.
function remarketing(listId: string, options?: { name?: string; bidAdjustment?: number }): AudienceRefremarketing('123456789')
remarketing('123456789', { name: 'All Visitors', bidAdjustment: 0.2 })customAudience(audienceId, options?)
Reference a custom audience.
function customAudience(audienceId: string, options?: { name?: string; bidAdjustment?: number }): AudienceRefcustomAudience('789', { name: 'File Management Searchers' })inMarket(categoryId, options?)
Reference an in-market audience segment.
function inMarket(categoryId: string, options?: { name?: string; bidAdjustment?: number }): AudienceRefinMarket('80432', { name: 'Business Software' })affinity(categoryId, options?)
Reference an affinity audience segment.
function affinity(categoryId: string, options?: { name?: string; bidAdjustment?: number }): AudienceRefaffinity('80101', { name: 'Technology Enthusiasts' })customerMatch(listId, options?)
Reference a customer match list (uploaded email/phone list).
function customerMatch(listId: string, options?: { name?: string; bidAdjustment?: number }): AudienceRefcustomerMatch('list-001', { name: 'Existing Customers' })Display-Specific
These helpers are for Google Display campaigns and are passed into targeting().
placements(...urls)
Target specific websites or YouTube channels where your ads will appear.
function placements(...urls: string[]): PlacementTargetimport { placements } from '@upspawn/ads'
placements('youtube.com', 'news.google.com', 'techcrunch.com')topics(...topicNames)
Target pages that match content topics from Google's topic taxonomy.
function topics(...topicNames: string[]): TopicTargetimport { topics } from '@upspawn/ads'
topics('Computers & Electronics', 'Business', 'Finance')contentKeywords(...kws)
Target pages containing specific keywords (contextual targeting).
function contentKeywords(...kws: string[]): ContentKeywordTargetimport { contentKeywords } from '@upspawn/ads'
contentKeywords('file management', 'pdf tools', 'batch rename')Meta Targeting
Meta targeting uses a separate set of helpers composed via metaTargeting().
metaTargeting(...rules)
Compose Meta targeting rules into a MetaTargeting object. Requires at least one geo() rule.
function metaTargeting(...rules: MetaTargetingRule[]): MetaTargetingimport { metaTargeting, geo, age, audience, interests } from '@upspawn/ads'
metaTargeting(
geo('US', 'DE'),
age(25, 65),
audience('Website Visitors 30d'),
...interests('Construction', 'BIM'),
)age(min, max)
Set age range for Meta targeting.
function age(min: number, max: number): MetaTargetingRuleminandmax: 13–65
import { age } from '@upspawn/ads'
age(25, 65) // target ages 25 to 65
age(18, 35) // target ages 18 to 35audience(nameOrId)
Reference a Meta custom audience by name (resolved at plan/validate time) or explicit ID.
function audience(nameOrId: string | { id: string }): AudienceMarkerimport { audience } from '@upspawn/ads'
audience('Website Visitors 30d') // name lookup — resolved at plan time
audience({ id: '23856789012345' }) // explicit ID — no lookup requiredexcludeAudience(nameOrId)
Exclude a Meta custom audience from delivery.
function excludeAudience(nameOrId: string | { id: string }): ExcludedAudienceMarkerimport { excludeAudience } from '@upspawn/ads'
excludeAudience('Existing Customers')
excludeAudience({ id: '23856789099999' })interests(...args)
Target by interest name (resolved via catalog or Meta Targeting Search API) or explicit { id, name }.
function interests(
...args: (string | { id: string; name: string })[]
): InterestMarker[]Returns an array of markers — spread into metaTargeting():
import { metaTargeting, geo, interests } from '@upspawn/ads'
metaTargeting(
geo('US'),
...interests('Construction', 'BIM Software'),
...interests({ id: '6003370250981', name: 'Architecture' }),
)Use ads search interests "<query>" to find interest names and IDs.
lookalike(source, config)
Create a lookalike audience from an existing audience.
function lookalike(
source: string | { id: string },
config: { geo: GeoTarget; percent: number },
): LookalikeMarkerpercent: 1–10 (percentage of population similarity)
import { lookalike, geo } from '@upspawn/ads'
lookalike('Website Visitors 30d', { geo: geo('US'), percent: 1 })
lookalike({ id: '23856789012345' }, { geo: geo('DE'), percent: 2 })Putting It Together
import {
google,
targeting,
geo,
languages,
weekdays,
hours,
device,
demographics,
audiences,
remarketing,
daily,
negatives,
} from '@upspawn/ads'
export default google.search('Search - Core', {
budget: daily(30),
bidding: 'maximize-conversions',
targeting: targeting(
geo('US', 'CA', 'GB'),
languages('en'),
weekdays(),
hours(8, 20),
device('mobile', 0.15),
device('tablet', -0.3),
demographics({ ageRanges: ['25-34', '35-44', '45-54'] }),
audiences(remarketing('123456', { bidAdjustment: 0.5 })),
),
negatives: negatives('free', 'open source', 'crack'),
})