Ad Campaigns

Update an ad set

Changed on

Changes an ad set's settings, such as its budget, bid strategy, status or delivery options.

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).
  • Meta only: send bidAmount WITHOUT bidStrategy to change the cap amount on an ad set whose strategy (its own, or the campaign's under CBO) is COST_CAP / LOWEST_COST_WITH_BID_CAP, leaving the strategy untouched. Send roasAverageFloor WITHOUT bidStrategy the same way to change the floor of a LOWEST_COST_WITH_MIN_ROAS ad set. Either field against an incompatible current strategy is a 400.
  • Meta CBO (the campaign holds the budget): the campaign also holds the bid strategy, so only bidAmount or roasAverageFloor is written on the ad set. A bidStrategy equal to the campaign's is accepted; a different one is a 409 (change it with PUT /v1/ads/campaigns/{campaignId}).

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 ad set whose campaign holds the budget (CBO), the response is 409 with code invalid_field_value. Send it to PUT /v1/ads/campaigns/{campaignId} instead.

Reddit Ads: budget changes the ad group's amount; an ad group that spends its campaign budget returns 422 (update the campaign instead), and Reddit cannot switch a published budget between daily and lifetime, so budget.type must match the current one (422 otherwise). name renames the ad group. bidStrategy maps to the ad group's bid_strategy: LOWEST_COST_WITHOUT_CAP = automatic bidding (BIDLESS), LOWEST_COST_WITH_BID_CAP = MANUAL_BIDDING with bidAmount as the bid, COST_CAP = MAXIMIZE_VOLUME with bidAmount as the cap; LOWEST_COST_WITH_MIN_ROAS returns 422.

status behaves exactly as PUT /v1/ads/ad-sets/{adSetId}/status describes: only the ad set's own switch is written, its ads keep theirs, and statusUpdated / statusSkipped report whether that switch was written or a live read showed it already in place.

Placements and targeting (Meta only): placements and targeting take the same shapes as POST /v1/ads/create. Meta replaces an ad set's targeting wholesale, so Zernio reads the live targeting first, changes only what the request names and writes the merged spec back: custom audiences, geo, age, interest groups and targeting_automation you do not send are kept. placements replaces the whole placement set, placements: null returns the ad set to automatic placements, and omitting it leaves placements as they are. Other platforms return 400 for either field before anything in the request is written (use PUT /v1/ads/{adId} with targeting where that platform supports it). The live read and the incomeTier lookup run before any other field is written, so a 502 or 422 from them leaves the ad set unchanged.

put/v1/ads/ad-sets/{adSetId}

Request

  • Base URL: https://zernio.com/api
  • URL: https://zernio.com/api/v1/ads/ad-sets/{adSetId}
  • Auth: HTTP bearer

Path parameters

adSetIdstring required

Platform ad set ID

Request body

platform'facebook' | 'instagram' | 'tiktok' | 'linkedin' | 'pinterest' | 'google' | 'twitter' | 'openai' | 'reddit' required
status'active' | 'paused'

Writes the ad set's own on/off switch (Meta: configured_status; X: the line item's entity_status ACTIVE / PAUSED), whatever delivery status its ads report. Omit if not toggling delivery state.

namestring

Rename the ad set on any supported platform: Meta, Google (the ad group), TikTok, LinkedIn (the campaign), Pinterest, X (the line item name), OpenAI and Reddit; platforms without a rename return 501. The new name is stored right away, so GET /v1/ads/ad-sets and GET /v1/ads/tree return it without a sync. 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).
bidAmountnumber

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 and X) to micros (× 1,000,000). Meta only: may be sent alone, WITHOUT bidStrategy, to update the cap amount on an ad set whose parent campaign is COST_CAP or LOWEST_COST_WITH_BID_CAP (the strategy is inherited from the campaign and is left untouched).

roasAverageFloornumber

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. Meta only: may be sent alone, WITHOUT bidStrategy, to update the floor on an ad set whose strategy (its own, or the campaign's under CBO) is LOWEST_COST_WITH_MIN_ROAS. Not supported on OpenAI (422).

valueRuleSetIdstring

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.

valueRulesAppliedboolean

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.

Response

Ad set updated

budgetLevel'adset'
status'active' | 'paused'

As in PUT /v1/ads/ad-sets/{adSetId}/status: delivery derived from the switches read back.

platformAdSetStatusstring nullable

The ad set's status read back from the platform, as in PUT /v1/ads/ad-sets/{adSetId}/status (Meta and Reddit return the ad set's effective_status); null when it could not be read.

platformCampaignStatusstring nullable
statusReadAtstring date-time nullable
statusUpdated0 | 1

1 when the ad set's switch was written.

statusSkipped0 | 1

1 when a live read showed it already in the requested state.

statusSkippedReasonsstring[]
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).
bidAmountnumber nullable
roasAverageFloornumber nullable
platformSpecificDataobject
targetingobject

Present when placements or targeting was sent. The ad set's full Meta targeting as written (Meta snake_case). The same snake_case object is stored as the ad set's and its ads' targeting.

Changes

    • info

      added the new optional request property /////

    • info

      added the new optional request property

    • info

      added the new optional request property

    • info

      added the non-success response with the status

    • info

      added the optional property to the response with the status