---
title: "Update an ad set"
method: PUT
path: "/v1/ads/ad-sets/{adSetId}"
tags: ["Ad Campaigns"]
---

# Update an ad set

`PUT /v1/ads/ad-sets/{adSetId}`

Ad-set-level writes. Use this for ABO budget updates, ad-set-scoped
pause/resume, bid-strategy edits, Meta value-rule-set attach/detach, and
Meta-only post-launch delivery settings via `platformSpecificData`. At
least one updatable field is required.

Value rule sets (Meta only, see `/v1/ads/value-rule-sets`):
- ATTACH or REPLACE: send `valueRuleSetId`. Attachment is driven by the id's
  presence, so `valueRulesApplied: true` is optional. Sending a different id
  replaces the previous association; there is no separate replace call.
- DETACH: send `valueRulesApplied: false` and OMIT `valueRuleSetId`.
- Sending `valueRulesApplied: false` TOGETHER with `valueRuleSetId` returns 400
  `mutually_exclusive_fields`. This is deliberate: Meta attaches the rule set
  whenever `value_rule_set_id` is present, even with `value_rules_applied` false,
  so echoing stored state while asking to detach would silently keep the bid
  adjustments live.
- Eligibility: only ad sets on `LOWEST_COST_WITHOUT_CAP` or `COST_CAP`. Meta
  rejects the rest server-side.
- Read back with `GET /v1/ads/ad-sets/{adSetId}?fields=value_rule_set_id`. Meta
  does not document `value_rules_applied` as a readable ad-set field, so the
  boolean cannot be read back.

Bid strategy compatibility (per Meta's spec):
- `LOWEST_COST_WITHOUT_CAP`: no `bidAmount`, no `roasAverageFloor`.
- `LOWEST_COST_WITH_BID_CAP` / `COST_CAP`: `bidAmount` REQUIRED (whole currency units).
- `LOWEST_COST_WITH_MIN_ROAS`: `roasAverageFloor` REQUIRED (decimal multiplier, e.g. 2.0 = 2.0x ROAS).

Delivery settings are validated by Meta against the campaign objective;
incompatible combinations (e.g. a billingEvent the optimization goal
doesn't allow) surface as 400s from Meta.

When updating `budget` on an ABO campaign: if the parent campaign is
CBO, the response is 409 with code BUDGET_LEVEL_MISMATCH — route to
PUT /v1/ads/campaigns/{campaignId} instead.

## Path parameters

- `adSetId` string, required

## Request body

- object
  - `platform` 'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'pinterest' | 'google' | 'twitter' | 'openai', required
  - `budget` object — Omit if not updating budget
    - `amount` number
    - `type` 'daily' | 'lifetime'
  - `status` 'active' | 'paused' — Omit if not toggling delivery state
  - `name` string — Rename the ad set (Meta only; other platforms return 501). At least one of budget/status/bidStrategy/name is required.
  - `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 — Bid cap in WHOLE currency units (USD: 5 = $5.00; JPY: 100 = ¥100). Required when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. Internally converted to Meta's smallest-denomination integer, or (on OpenAI) to micros (× 1,000,000).
  - `roasAverageFloor` number — Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Required when bidStrategy is LOWEST_COST_WITH_MIN_ROAS. Sent to Meta as `bid_constraints.roas_average_floor` × 10000. Not supported on OpenAI (422).
  - `valueRuleSetId` string — Meta only (other platforms return 501). Value rule set to attach to this ad set, from `/v1/ads/value-rule-sets`. Sending a different id replaces the current association. To DETACH, send `valueRulesApplied: false` and omit this field.
  - `valueRulesApplied` boolean — Meta only (other platforms return 501). `false` DETACHES the ad set's value rule set and must be sent WITHOUT `valueRuleSetId`; the combination returns 400. `true` is optional when attaching, since attachment is driven by `valueRuleSetId`, and requires it to be present.
  - `platformSpecificData` object — Platform-specific post-launch delivery settings. The platform is implied by the `platform` body param. Meta only; other platforms return 400. Unknown keys are rejected.
    - `optimizationGoal` string — Meta ad-set optimization_goal (e.g. OFFSITE_CONVERSIONS, LANDING_PAGE_VIEWS).
    - `billingEvent` string — Meta ad-set billing_event (e.g. IMPRESSIONS, LINK_CLICKS, THRUPLAY).
    - `startDate` string — Ad set start_time (ISO 8601).
    - `endDate` string — Ad set end_time (ISO 8601).
    - `promotedObject` object — Meta ad-set promoted_object, forwarded verbatim (same shape as /v1/ads/create). Unknown keys are rejected with 400.
      - `pixelId` string
      - `customEventType` string
      - `customEventStr` string — Pixel custom-event name (custom_event_str); requires customEventType OTHER. Same pairing rules as /v1/ads/create.
      - `pageId` string
      - `applicationId` string
      - `objectStoreUrl` string
      - `customConversionId` string
      - `productCatalogId` string
      - `productSetId` string
      - `offlineConversionDataSetId` string
      - `whatsappPhoneNumber` string

## Response `200`

Ad set updated

- object
  - `budget` AdBudget — Budget amount in the ad account's native currency (see the campaign's `currency` field for the code).
    - `amount` number, required
    - `type` 'daily' | 'lifetime', required
  - `budgetLevel` 'adset'
  - `status` 'active' | 'paused'
  - `statusUpdated` integer
  - `statusSkipped` integer
  - `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, nullable
  - `roasAverageFloor` number, nullable
  - `platformSpecificData` object

## Other responses

- `400` — Invalid input
- `401` — Unauthorized
- `404` — Ad set not found
- `409` — Campaign is CBO — route to /v1/ads/campaigns/{campaignId} instead
- `422` — bidStrategy is LOWEST_COST_WITH_MIN_ROAS on OpenAI (unsupported: no ROAS-based bidding)
- `501` — bidStrategy not supported on the platform (Meta, TikTok, and OpenAI only)

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/versions/51932b099b2f/schema)
