---
title: "Create portfolio bid strategy"
method: POST
path: "/v1/ads/bid-strategies"
tags: ["Ad Campaigns"]
---

# Create portfolio bid strategy

`POST /v1/ads/bid-strategies`

Creates a standalone bid strategy shared across campaigns. Attach it to a campaign with `portfolioBidStrategyId` on POST /v1/ads/create, PUT /v1/ads/campaigns/{campaignId}, or PUT /v1/ads/ad-sets/{adSetId}. Attaching a strategy aligned to a shared budget fails there with a 400 (Google's `BIDDING_STRATEGY_AND_BUDGET_MUST_BE_ALIGNED`); this is not retryable.

## Request body

- object
  - `accountId` string, required — Google ads SocialAccount id.
  - `adAccountId` string — Platform ad account ID (Google customer ID, digits only). Defaults to the account's connected customer.
  - `customerId` string — Alias of adAccountId, kept for existing callers
  - `name` string, required
  - `type` 'TARGET_CPA' | 'TARGET_ROAS' | 'MAXIMIZE_CONVERSIONS' | 'MAXIMIZE_CONVERSION_VALUE', required
  - `targetCpa` number — Required when type is TARGET_CPA, in the account's currency units.
  - `targetRoas` number — Required when type is TARGET_ROAS; a multiplier (2.0 = 2.0x).

## Response `201`

Bid strategy created

- object
  - `strategy` object
    - `customerId` string
    - `id` string — Numeric bid strategy id; pass as portfolioBidStrategyId or in the {strategyId} path.
    - `resourceName` string

## Other responses

- `400` — Invalid input, or Google rejected the strategy (e.g. shared-budget alignment). The message carries Google's error.
- `401` — Unauthorized
- `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.
- `422` — No Google Ads customer accounts on this connection. Reconnect Google Ads.
- `429` — Google Ads operations budget exhausted; retry later.
- `501` — Only available on Google Ads accounts

## Changes

- **2026-09-23** `dd3865482f9f` — 2 info
  - added the new optional request property `adAccountId`
  - request property `customerId` deprecated
- **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` — 7 info
  - added the non-success response with the status `409`
  - added the optional property `code` to the response with the `404` status
  - added the optional property `details` to the response with the `404` status
  - added the optional property `param` to the response with the `404` status
  - …3 more
- **2026-09-08** `d7a8fa118ef0` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/bid-strategies/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/dd3865482f9f?raw)
