---
title: "Read a campaign's current bidding"
method: GET
path: "/v1/ads/campaigns/{campaignId}/bidding"
tags: ["Ad Campaigns"]
---

# Read a campaign's current bidding

`GET /v1/ads/campaigns/{campaignId}/bidding`

Read of the campaign's bidding strategy on Google, cached for the quota window, for
pre-filling the bid strategy block before a PUT to /v1/ads/campaigns/{campaignId}.
Google Ads only; `platform` is required and rejected when it is anything else, since
a `campaignId` is not globally unique. The response carries `cachedAt` and `stale`,
set when a quota-exhausted call falls back to the last-good copy instead of a live
read.

Maps Google's bidding strategy onto the same triplet PUT accepts: `LOWEST_COST_WITHOUT_CAP`
(Maximize Conversions, no target), `COST_CAP` + `bidAmount` (Target CPA), `LOWEST_COST_WITH_MIN_ROAS`
+ `roasAverageFloor` (Target ROAS), `LOWEST_COST_WITH_BID_CAP` + `bidAmount` (Maximize Clicks with
a CPC ceiling). A campaign on a portfolio strategy returns `portfolio` (id + name) and
`bidSpec.portfolioBidStrategyId` instead of the triplet. Anything else (Manual CPC, Target
Impression Share, ...) returns `bidSpec: null`; show `biddingStrategyType` as-is.

## Path parameters

- `campaignId` string, required

## Query parameters

- `accountId` string, required
- `platform` 'google', required
- `customerId` string

## Response `200`

Campaign bidding

- object — A Google campaign's current bidding, mapped onto the same triplet PUT /v1/ads/campaigns/{campaignId} accepts.
  - `campaignId` string
  - `channel` 'SEARCH' | 'DISPLAY' — campaign.advertising_channel_type. COST_CAP's underlying Google field differs by channel; see bidStrategy on PUT.
  - `biddingStrategyType` string — Google's raw enum: MAXIMIZE_CONVERSIONS, TARGET_CPA, MAXIMIZE_CONVERSION_VALUE, TARGET_ROAS, TARGET_SPEND, MANUAL_CPC, TARGET_IMPRESSION_SHARE, or another Google adds later.
  - `bidSpec` object, nullable — Null when the campaign is on a strategy PUT does not model (Manual CPC, Target Impression Share, ...); show biddingStrategyType instead in that case.
    - `bidStrategy` 'LOWEST_COST_WITHOUT_CAP' | 'LOWEST_COST_WITH_BID_CAP' | 'COST_CAP' | 'LOWEST_COST_WITH_MIN_ROAS' — Meta bid strategy. Same enum applies at campaign and ad-set level; ad-set value (when set) overrides campaign-level. Cross-field rules: - `LOWEST_COST_WITHOUT_CAP` (default): auto-bid, forbids `bidAmount` and `roasAverageFloor`. - `LOWEST_COST_WITH_BID_CAP` / `COST_CAP`: require `bidAmount` (whole currency units). - `LOWEST_COST_WITH_MIN_ROAS`: requires `roasAverageFloor` (decimal multiplier, 2.0 = 2.0x). Source: facebook-business-sdk-codegen api_specs/specs/enum_types.json (`AdSet_bid_strategy`, `Campaign_bid_strategy`).
    - `bidAmount` number — Whole currency units. Present for COST_CAP and LOWEST_COST_WITH_BID_CAP, and omitted when the campaign is on a bare TARGET_SPEND with no CPC ceiling set.
    - `roasAverageFloor` number — Decimal ROAS multiplier (2.0 = 2.0x). Present for LOWEST_COST_WITH_MIN_ROAS.
    - `portfolioBidStrategyId` string — Present alone (bidStrategy omitted) when the campaign is on a portfolio strategy; see portfolio.
  - `portfolio` object, nullable — Set only when the campaign is on a portfolio bid strategy (campaign.bidding_strategy); null otherwise.
    - `id` string
    - `name` string
  - `cachedAt` string, date-time, nullable — When this data was fetched from Google. Null when it was never served from cache.
  - `stale` boolean — True when Google's daily API quota was exhausted and this is the last successful fetch, not a live read.

## Other responses

- `400` — Invalid input (accountId, customerId, or a non-numeric campaignId), or a platform other than "google"
- `401` — Unauthorized
- `403` — Ads access required. Legacy plans need the Ads add-on; included by default on usage-based plans.
- `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.
- `501` — Not a Google Ads account: the connection behind accountId resolves to another platform.

## Changes

- **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-10** `e70ed06e7150` — 2 info
  - added the media type `application/json` for the response with the status `404`
  - added the non-success response with the status `409`
- **2026-09-08** `d7a8fa118ef0` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/campaigns/:campaignId/bidding/get.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/106013ac73b8?raw)
