---
title: "Suggested bid and budget bounds"
method: POST
path: "/v1/ads/targeting/bid-pricing"
tags: ["Ad Targeting"]
---

# Suggested bid and budget bounds

`POST /v1/ads/targeting/bid-pricing`

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.

## Request body

- object
  - `accountId` string, required — Zernio account ID (LinkedIn).
  - `adAccountId` string, required — LinkedIn ad account ID (numeric).
  - `spec` TargetingSpec, required — Normalized, platform-agnostic ad-targeting spec. Every field is optional, an empty object targets the platform's default broadest audience. Field names are camelCase and identical across `POST /v1/ads/create` (the `targeting` object), `POST /v1/ads/targeting/reach-estimate`, and `saved_targeting` audiences, so a spec resolved once can be reused verbatim. Entity ids (`regions[].key`, `cities[].key`, `zips[].key`, `metros[].key`, `interests[].id`, `behaviors[].id`) are the platform's opaque identifiers resolved via `GET /v1/ads/targeting/search`. A spec is therefore meaningful only for the platform it was built against, except the portable fields (`countries`, `ageMin`/`ageMax`, `gender`, `incomeTier`, `languages`) which carry across platforms. Fields a platform cannot honour are rejected at create time with `INVALID_FIELD_VALUE` naming the offending field (not silently dropped).
    - `userOs` string[] — Meta only. Operating systems and version ranges, such as iOS_ver_14.0_and_above or Android. Emitted as user_os. May also be supplied inside targeting.
    - `userDevice` string[] — Meta only. Device models such as iPhone. Emitted as user_device. May also be supplied inside targeting.
    - `countries` string[] — ISO 3166-1 alpha-2 country codes (e.g. ['US']).
    - `regions` union[] — Region/state targeting. `key` is the platform location ID from /v1/ads/targeting/search?dimension=geo&geoType=region. An entry may also be that id as a plain string (`"20321"` is `{ key: "20321" }`).
      - union
        - string
        - object
          - `key` string, required
          - `name` string
    - `cities` union[] — City targeting. Optional `radius` + `distanceUnit` extend beyond the city limits; both must be set together or both omitted. `radius` is only honoured on platforms whose capability map allows city radius (Meta). An entry may also be the city id as a plain string (`"1006410"` is `{ key: "1006410" }`).
      - union
        - string
        - object
          - `key` string, required
          - `name` string
          - `radius` number — Radius around the city. Requires distanceUnit. Meta enforces a minimum city radius (~17 km / 10 mi); smaller values resolve to a 0-size audience and the ad fails at launch. For a tighter catchment use customLocations (lat/lng), which allows a smaller radius.
          - `distanceUnit` 'mile' | 'kilometer' — Required if radius is set.
    - `zips` object[] — Postal/ZIP targeting. `key` is the platform's postal location ID (e.g. Meta `US:94304`). Supported on Meta, Google, TikTok, Pinterest, X.
      - `key` string, required
      - `name` string
    - `metros` object[] — DMA / metro-area targeting. `key` is the platform's metro ID (e.g. Meta `DMA:807`).
      - `key` string, required
      - `name` string
    - `countryGroups` string[] — Meta only. Continents and trade blocs (`geo_locations.country_groups`), for targeting a whole region without listing its countries. Combines with `countries` rather than replacing it, and is also accepted under `excludedLocations`. Discoverable via `GET /v1/ads/targeting/search?dimension=geo&geoType=country_group`.
    - `customLocations` object[] — Point-radius (lat/lng) targeting (Meta custom_locations / Google proximity). Honoured on Meta and Google; ignored on platforms without radius support.
      - `latitude` number, required
      - `longitude` number, required
      - `radius` number, required — Positive radius around the point.
      - `distanceUnit` 'mile' | 'kilometer', required
      - `name` string
      - `address` string — Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.
    - `excludedLocations` object — Geo to exclude from the audience. Mirrors the inclusion geo shape: excluded cities can carry a radius catchment and excluded custom (lat/lng) pins are supported, both on Meta (excluded_geo_locations).
      - `countries` string[]
      - `countryGroups` string[] — Meta only. Continents and trade blocs to exclude (`excluded_geo_locations.country_groups`).
      - `regions` object[]
        - `key` string, required
        - `name` string
      - `cities` object[] — Cities to exclude. Optional `radius` + `distanceUnit` exclude a catchment around the city (both must be set together or both omitted); Meta honours the radius on excluded cities.
        - `key` string, required
        - `radius` number — Radius around the excluded city. Requires distanceUnit.
        - `distanceUnit` 'mile' | 'kilometer' — Required if radius is set.
      - `zips` object[]
        - `key` string, required
        - `name` string
      - `places` object[] — Named points of interest to exclude. `key` from /v1/ads/targeting/search.
        - `key` string, required
      - `neighborhoods` object[] — Named neighbourhood areas to exclude. `key` from /v1/ads/targeting/search.
        - `key` string, required
      - `customLocations` object[] — Point-radius (lat/lng) pins to exclude (Meta excluded_geo_locations.custom_locations). Mirrors the inclusion customLocations shape.
        - `latitude` number, required
        - `longitude` number, required
        - `radius` number, required — Positive radius around the point.
        - `distanceUnit` 'mile' | 'kilometer', required
        - `name` string
        - `address` string — Optional label, sent to Meta as `address_string`. latitude/longitude take precedence for the pin location.
    - `ageMin` integer — Minimum age. Applied on Meta, TikTok and Pinterest; ignored on Google, LinkedIn and X. Each platform clamps to its own range: Meta and Pinterest effectively cap at 65 (65 = 65+), TikTok maps up to 100. Pinterest has no under-18 bucket, so an ageMin below 18 starts at 18 there.
    - `ageMax` integer — Maximum age. Same per-platform application and clamping as ageMin.
    - `gender` 'all' | 'male' | 'female' — Restrict by gender. 'all' (default) targets everyone. Applied on Meta, TikTok and Pinterest. Ignored on Google, LinkedIn and X.
    - `incomeTier` 'top_5' | 'top_10' | 'top_10_25' | 'top_25_50' — Normalized household-income tier (ZIP/percentile based). Meta and TikTok express all four. Google maps only `top_10` (its INCOME_RANGE_90_UP); other tiers on Google, and any income tier on LinkedIn / X / Pinterest, are rejected. On Meta, income/zip targeting requires the relevant `specialAdCategories` to be unset (housing/employment/credit ads cannot use it).
    - `languages` string[] — Language codes restricting the audience by language. On Meta, ISO 639-1 codes (e.g. ['en']); a bare code targets all regional variants ("en" = all English), or use a region-qualified code ("en_GB", "pt_BR") for a specific one. Unknown codes are rejected.
    - `interests` object[] — Interest entities from /v1/ads/targeting/search?dimension=interest. Each carries the platform's opaque id.
      - `id` string, required
      - `name` string
    - `behaviors` object[] — Behaviour entities from /v1/ads/targeting/search?dimension=behavior. Supported on Meta and TikTok.
      - `id` string, required
      - `name` string
    - `workPositions` object[] — Meta only. Job title entities from /v1/ads/targeting/search?dimension=workPosition. Not interchangeable with the LinkedIn `jobTitles` URN fragments.
      - `id` string, required
      - `name` string
    - `workEmployers` object[] — Meta only. Employer entities from /v1/ads/targeting/search?dimension=workEmployer.
      - `id` string, required
      - `name` string
    - `workIndustries` object[] — Meta only. Work-industry entities from /v1/ads/targeting/search?dimension=workIndustry. Not interchangeable with the LinkedIn `industries` URN fragments.
      - `id` string, required
      - `name` string
    - `industries` string[] — LinkedIn B2B only. Industry URN id fragments, or the full urn:li:industry:* URN from /v1/ads/targeting/search?dimension=industry.
    - `companySizes` string[] — LinkedIn B2B only. Single-letter size codes (A to I), or the full urn:li:staffCountRange:* URN from /v1/ads/targeting/search?dimension=companySize.
    - `seniorities` string[] — LinkedIn B2B only. Seniority URN id fragments, or the full urn:li:seniority:* URN from /v1/ads/targeting/search?dimension=seniority.
    - `jobFunctions` string[] — LinkedIn B2B only. Function URN id fragments, or the full urn:li:function:* URN from /v1/ads/targeting/search?dimension=jobFunction.
    - `audienceInclude` string[] — Platform audience IDs to include, as returned by GET /v1/ads/audiences (Meta custom audience ids, TikTok audience ids, Pinterest customer list ids, LinkedIn segment ids (the platformAudienceId from GET /v1/ads/audiences; Zernio resolves it to the targetable LinkedIn ad segment, an unknown id returns 400), Google user list ids, X custom audience ids). Not supported on OpenAI (400).
    - `audienceExclude` string[] — Platform audience IDs to exclude; same ID formats as audienceInclude. Not supported on OpenAI (400).
  - `campaignType` 'TEXT_AD' | 'SPONSORED_UPDATES' | 'SPONSORED_INMAILS' — Defaults to SPONSORED_UPDATES.
  - `bidType` 'CPM' | 'CPC' | 'CPV' — Defaults to CPM.
  - `matchType` 'EXACT' | 'AUDIENCE_EXPANDED' — Defaults to EXACT.
  - `currency` string — ISO 4217, defaults to USD.
  - `objectiveType` string — LinkedIn objectiveType, e.g. WEBSITE_VISIT, LEAD_GENERATION, VIDEO_VIEW.
  - `optimizationTargetType` string — LinkedIn optimizationTargetType, e.g. MAX_CLICK, MAX_IMPRESSION.
  - `dailyBudget` number — Optional daily budget in whole account-currency units. LinkedIn refines the suggested bid to this budget.

## Response `200`

Pricing insights

- object
  - `available` boolean, required
  - `pricing` object, nullable — LinkedIn's adBudgetPricing element. Null when LinkedIn has no data for the combination.
    - `bidLimits` object
      - `min` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
      - `max` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
    - `suggestedBid` object
      - `min` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
      - `default` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
      - `max` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
    - `dailyBudgetLimits` object
      - `min` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
      - `default` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".
      - `max` MoneyAmount
        - `amount` string, required — Amount as a decimal string, e.g. "88.59".
        - `currencyCode` string, required — ISO 4217 currency code, e.g. "USD".

## Other responses

- `400` — Invalid targeting or unsupported objective/optimization/bid combination.
- `401` — Unauthorized
- `403` — Ads access required.
- `404` — The account or requested resource was not found or is not accessible. An account ID may have been disconnected and removed. Read GET /v1/accounts for current account IDs.
- `409` — The account exists but is inactive or needs reconnection. Reconnect it, then read GET /v1/accounts for its current account ID before retrying. Code: ads_connection_required.

## Changes

- **2026-09-25** `2c04683ce694` — 2 breaking, 6 warning, 10 info
  - the `spec/allOf[#/components/schemas/TargetingSpec]/cities/items/` request property type changed from `object` to no type
  - the `spec/allOf[#/components/schemas/TargetingSpec]/regions/items/` request property type changed from `object` to no type
  - removed the request property `spec/allOf[#/components/schemas/TargetingSpec]/cities/items/distanceUnit`
  - removed the request property `spec/allOf[#/components/schemas/TargetingSpec]/cities/items/key`
  - …14 more
- **2026-09-16** `3e6ddf2a99ea` — 2 info
  - added the optional property `details/budgetScope` to the response with the `404` status
  - added the optional property `details/budgetScope` to the response with the `409` status
- **2026-09-15** `0dba7d004d75` — 4 info
  - added the optional property `details/quotaExhausted` to the response with the `404` status
  - added the optional property `details/quotaExhausted` to the response with the `409` status
  - added the optional property `details/quotaScope` to the response with the `404` status
  - added the optional property `details/quotaScope` to the response with the `409` status
- **2026-09-14** `a23eb241746a` — 2 info
  - added the new optional request property `spec/allOf[#/components/schemas/TargetingSpec]/countryGroups`
  - added the new optional request property `spec/allOf[#/components/schemas/TargetingSpec]/excludedLocations/countryGroups`
- …earlier changes not shown

[Full history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/targeting/bid-pricing/post.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/b2325332041a?raw)
