---
name: set-up-dynamic-ad-customizers
description: >-
  Connects live business data, current prices, stock status, active promotions, to responsive search ad copy
  through ad customizer attributes, so the ad text updates itself whenever the underlying feed changes. Reach for
  this when a client needs accurate prices inside ad copy, inventory-driven messaging, or sale copy that must
  expire on its own schedule without anyone remembering to edit ads. Do not use it for per-keyword phrasing
  control (that is set-up-keyword-level-ad-customizers), and do not use it to compose the base ad itself (that is
  write-compelling-rsas). Skip entirely when the pricing or inventory source cannot be verified, automating an
  untrustworthy feed just publishes wrong prices faster.
---
# Feed-Driven Ad Customizers for Prices, Stock, and Promotions

## Purpose
Keeps ad copy synchronized with volatile business data. Instead of hand-editing headlines every time a price
moves or a sale ends, you define customizer attributes, maintain their values in a feed, and reference them in
RSA text with placeholder syntax. The ad then renders the current value at serve time, falling back to a default
you control when no value exists.

## When to run
- Ad copy quotes prices and the catalog reprices weekly or faster.
- Messaging should change with stock levels ("in stock", "back soon").
- Time-boxed promotions need to appear at launch and vanish at the deadline without manual edits.
- One RSA must show different values in different campaigns or ad groups from a single data source.

## When NOT to run
- You need singular/plural or descriptor control per keyword, run `set-up-keyword-level-ad-customizers`.
- The RSA itself has not been built or is weak, run `write-compelling-rsas` first.
- The data source is unreliable or unverifiable, a broken feed publishes wrong claims at scale; fix the source first.
- Regulated pricing claims (financing rates, medical offers) without a compliance review of every dynamic value.

## Prerequisites
- A live RSA (or a plan to create one) in the target ad group.
- A system of record for the dynamic values: spreadsheet, ecommerce platform, or ERP export.
- Values reconciled against the source system at least once before any automation.
- A pilot scope agreed with the user: one campaign or ad group, roughly 10 keywords.

## Procedure
1. **Consult the policy guardrail.** Before the first Google Ads write of the session, call
   `gads_policy_guardrail` and apply its guidance, dynamic pricing and scarcity claims are exactly the
   territory where policy problems appear.
2. **Design the attribute schema.** List which values must be dynamic (price, product name, discount,
   stock note, promo text) and assign each a name and data type. Prefer the Text type for prices when you
   want formatting control: keep only the number in the feed and place the currency symbol in the ad text
   itself. If you use the Price type, every value must carry its currency symbol; Percent-type values must
   include the % sign.
3. **HUMAN STEP (outside VigilDog): build and upload the feed.** Customizer attributes and their values are
   managed through the Google Ads bulk upload / business data interface, no VigilDog tool writes them.
   Rules for whoever builds the file: attribute definition rows come before value rows; targeting keywords
   in the feed are written bare, with no match-type brackets; scope the first upload to the pilot ad group only.
4. **Draft customizer-bearing copy.** Use `gads_generate_rsa_copy` to produce headlines and descriptions
   that embed `{CUSTOMIZER.AttributeName:default}` placeholders. Every default must read as finished,
   natural copy on its own, assume it will serve, because for any keyword without a value, it will.
5. **Apply the copy to the ad.** Use `gads_update_ad` for an existing RSA or
   `gads_create_responsive_search_ad` for a new one. Preview first (validate_only is the default), show the
   user the exact rendered assets including every default, and apply only after explicit user approval.
6. **HUMAN STEP (outside VigilDog): render check.** In the Ad Preview and Diagnosis tool, test at least five
   keywords that have feed values. Confirm real values render (not defaults), price formatting is correct,
   and defaults appear only for keywords deliberately left out of the feed.
7. **Monitor approvals.** Call `gads_get_disapproved_ads` daily for the first week after the change. Dynamic
   values can trip pricing and misrepresentation policies that the static copy never did.
8. **HUMAN STEP (outside VigilDog): automate the sync** once the pilot is clean, schedule a recurring
   Google Sheets upload or connect a feed tool, per the decision rules below. Verify the first scheduled run
   actually executed.
9. **Scale.** Extend the feed to more campaigns and keywords (HUMAN STEP for the upload), then repeat
   step 5 per additional RSA, each edit previews first and commits only after user approval. Re-run the
   render check on a sample of new entries.

## Decision rules
- **Sync method by volume and volatility:** under ~50 items changing weekly or less → manual uploads are
  fine; ~50–200 items changing daily → scheduled spreadsheet sync; 200+ items or intraday price moves →
  a feed management tool with hourly pushes.
- **Failed upload behavior:** Google keeps serving the last successfully uploaded values, it does not fall
  back to defaults. A silent sync failure therefore means stale prices in live ads. Whoever owns the sync must
  alert on failures, not just on errors in the file.
- **Scarcity gate:** "Only N left" style copy is allowed only when N comes from real inventory data. No
  verifiable count, no scarcity claim.
- **Out-of-stock handling:** either delete the product's row (defaults take over) or flip a stock-status
  attribute to neutral messaging, and pause the affected keywords if the product will be gone for long.
- **Pilot-first rule:** nothing scales past one ad group until a full render check has passed on 5+ keywords.
- **Per-scope values:** the same keyword may carry different values in different campaigns; the feed's
  campaign and ad-group columns decide which value wins, with the account-level value as the universal fallback.
- **Countdown deadlines:** for date-anchored urgency, the built-in countdown function with a fallback word is
  often cleaner than a customizer attribute, it expires by itself. But any promo attribute referenced elsewhere
  in the ad still needs cleanup at the deadline, or the headline and description will contradict each other.
- **Attribute naming stability:** choose descriptive names before the first upload and never rename casually, every ad referencing the old name silently falls back to defaults after a rename.
- **Multi-market currencies:** one price attribute reused across country campaigns renders one currency
  everywhere. Use per-market attributes or campaign-scoped values so each market shows its own currency.

## Common failure modes
- **A default that breaks the sentence.** The placeholder default was written as a filler word, and when it
  fires the headline reads as nonsense. Write every default as shippable copy and review the ad with all
  defaults substituted in.
- **Number-only values in a Price-type attribute.** The upload rejects them or renders them oddly. Add
  currency symbols, or switch that attribute to Text and format in the ad.
- **Bracketed keywords in the feed.** They never match anything, so every impression serves defaults and
  the whole setup silently does nothing. Feed keywords are always written bare.
- **Expired promotion still rendering.** The sale ended but the feed row was never updated. Tie promo rows
  to end dates in the source data and check the feed whenever an offer starts or ends.
- **Scaling on faith.** The pilot was skipped and a formatting bug shipped to the entire catalog at once.
  Always validate the ~10-keyword pilot before expanding.
- **Orphaned syntax after an attribute rename.** Someone tidied attribute names in the feed and every ad
  referencing the old spelling quietly reverted to defaults. Treat attribute names as an API contract.
- **No named feed owner.** The setup worked at launch, then the person who understood the sync left and
  prices drifted for weeks. Record who owns the feed and where its source lives before calling this done.

## Documentation
Record the final attribute schema (names, types, scopes), the sync method and owner, and the list of ads
carrying customizer syntax in the account notes. Future editors must be able to see which ads depend on
which attributes before they touch either side.

## Related skills
- `write-compelling-rsas`, build the base RSA before wiring dynamic values into it.
- `set-up-keyword-level-ad-customizers`, the sibling technique for relevance control; the two can coexist
  in one account since they solve different problems.
- `rsa-testing-with-the-iteration-loop`, once the dynamic RSA is live and stable, feed it into the ongoing
  testing cadence.
- `resolve-ad-disapprovals`, if step 7 surfaces policy hits.
- `improve-expected-ctr`, dynamic price and promo copy is one of the stronger levers when click-through
  is the diagnosed weakness.
