---
title: "Change a campaign bidding strategy"
method: POST
path: "/api/v1/tools/google_update_bid_strategy/execute"
tags: ["Google Ads"]
---

# Change a campaign bidding strategy

`POST /api/v1/tools/google_update_bid_strategy/execute`

## Request

- Base URL: `https://adako.ai`
- URL: `https://adako.ai/api/v1/tools/google_update_bid_strategy/execute`
- Auth: HTTP bearer

Changes how a campaign bids: maximise conversions (optionally with a target CPA), maximise conversion value (optionally with a target ROAS), maximise clicks, or manual CPC.
Use when: the user has said what they want to optimise for and, for a target, the number they want.
Do not use when: the campaign is less than two weeks old or has fewer than ~15 conversions in the last 30 days — Smart Bidding needs data, and switching resets the learning period for about a week, during which cost per conversion usually gets worse before it gets better. Say that first.
Before changing anything the tool checks two things. If the campaign is driven by a *portfolio* strategy it refuses, names the portfolio and says how many campaigns share it; changing what that portfolio targets is then possible only with portfolio_strategy_id passed explicitly, because it moves every campaign on it. If you ask for conversion-based bidding it checks that the account actually has a working conversion action, and refuses with an explanation if it does not.
Moving one campaign between strategies is separate and safe for the others: attach_portfolio_strategy_id puts this campaign on an existing portfolio (from google_list_bidding_strategies), and detach_from_portfolio takes it off and gives it the strategy you pass. Neither touches the portfolio or the other campaigns on it.
The preview shows the before and after. Read-back confirms what Google stored.
If you are unsure which account, campaign or period the user means, ask them — do not guess ids or dates.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `arguments` object, required
    - `customer_id` string: Google Ads customer id (10 digits, dashes optional). Omit to use the primary account; list_connected_accounts shows the valid ids.
    - `campaign_id` string, required: Campaign id as returned by google_list_campaigns.
    - `strategy` 'MAXIMIZE_CONVERSIONS' | 'MAXIMIZE_CONVERSION_VALUE' | 'TARGET_SPEND' | 'MANUAL_CPC': MAXIMIZE_CONVERSIONS (optionally with a target CPA), MAXIMIZE_CONVERSION_VALUE (optionally with a target ROAS), TARGET_SPEND (shown as "Maximize clicks" in Google Ads) or MANUAL_CPC. Required unless attach_portfolio_strategy_id moves the campaign onto a portfolio, which decides the bidding itself.
    - `target_cpa` number: Target cost per conversion as a decimal in the account currency. Only with MAXIMIZE_CONVERSIONS. Rounded to the smallest amount Google bills in that currency.
    - `target_roas` number: Target return on ad spend as a multiplier (4 means 400%). Only with MAXIMIZE_CONVERSION_VALUE.
    - `enhanced_cpc` boolean: Retired by Google and refused by the API: passing true returns an error explaining what to use instead. Kept so older callers get that explanation rather than a raw platform error. Leave it unset.
    - `portfolio_strategy_id` string: Required when the campaign is driven by a portfolio strategy and you are changing that strategy (which changes every campaign on it). Pass the id the refusal message gave you, after telling the user how many campaigns share it. To move this campaign onto a portfolio, or off one, use attach_portfolio_strategy_id or detach_from_portfolio instead.
    - `attach_portfolio_strategy_id` string: Move this one campaign onto an existing portfolio (shared) bidding strategy, from google_list_bidding_strategies. The portfolio then decides its bidding, and nothing about the other campaigns on it changes. Its own strategy and targets are replaced, so pass no strategy with it.
    - `detach_from_portfolio` boolean: Take this one campaign off the portfolio strategy that drives it and give it the strategy in `strategy` instead. The portfolio and every other campaign on it are untouched.
    - `idempotency_key` string: Optional caller-supplied key; identical keys never execute twice.

## Response `200`

The tool ran. A write returns proposal_id and approve_url while the change waits for approval.

- SuccessEnvelope
  - `success` unknown, required
  - `tool` string, required
  - `data` object, required: Machine-readable result.
  - `markdown` string, required: The same result written for a person or a model.
  - `quota` Quota: Task usage for the current billing period.
    - `plan` string
    - `used` integer
    - `limit` integer
    - `period_end` string
    - `upgrade_url` string
  - `proposal_id` string: Present for writes. Nothing changes on the ad platform until it is approved.
  - `approve_url` string: Where a person approves the proposal.
  - `request_id` string, required

## Other responses

- `400`: Invalid arguments, or the ad account could not be resolved.
- `401`: Missing, invalid, revoked or expired API key.
- `402`: Monthly task quota used up, or the plan does not include this tool.
- `403`: The connected ad account lacks the access level this tool needs.
- `404`: Unknown tool name.
- `409`: Not connected, reconnect needed, confirmation required, a proposal already pending or no longer pending, an identical create that failed earlier today (proposal_failed_before), a create that duplicates an approved one (duplicate_create), the ad-account limit of the plan reached (account_limit), or an Idempotency-Key reused with different arguments.
- `429`: Rate limited by Adako or by the ad platform. See Retry-After.
- `500`: Unexpected error inside Adako.
- `502`: The ad platform returned an error.

---

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