Migrating to creative transformers (3.1)
AdCP 3.1 introduces transformers — the creative analog of a media-buy product: an agent-offered, account-scoped, selectable unit of build capability (a voice, model, style, or director) with a typed configuration surface and per-account pricing, discovered vialist_transformers and selected with transformer_id on build_creative.
Because a transformer carries its own input/output formats and its own pricing, three things that 3.0 hung on the format are now redundant and are deprecated:
Format.input_format_ids/Format.output_format_idsFormat.pricing_options- the
input_format_ids/output_format_idsdiscovery filters onlist_creative_formats
deprecated: true but still validate and still function through the 3.1–3.x line. Act before 4.0. The hazards below are about silent degradation over the window, not hard breaks.
What changed
| Surface | 3.0 | 3.1 | Removed |
|---|---|---|---|
| Build-capability discovery | filter list_creative_formats on input_format_ids / output_format_ids; read Format.input_format_ids / output_format_ids | discover via list_transformers (each transformer declares its own I/O signature) | 4.0 |
| Creative/transform pricing | Format.pricing_options (per format) | transformer.pricing_options (per transformer; include_pricing + account on list_transformers) | 4.0 |
list_creative_formats input_format_ids / output_format_ids filters | supported | deprecated: true — use list_transformers filters + brief | 4.0 |
Migrate
Format I/O signature → transformer
A transformer declares the formats it accepts and produces directly, so build capability is a property of the selectable unit, not a relationship hung on a format. Before (3.0) — a transform format declares what it consumes/produces:test=false
list_transformers):
test=false
Format pricing → transformer pricing
Format.pricing_options moves to transformer.pricing_options (same vendor-pricing-option shape; per_unit is typical). The applied option is echoed per-leaf on the build_creative response and reconciled via report_usage, unchanged.
Per-output pricing does not survive the move unchanged.Format.pricing_optionscould price each output format differently;transformer.pricing_optionsis one rate card for the whole transformer with no edge to a specificoutput_format_id. A multi-publisher template that priced outputs differently must split into one transformer per price point (e.g. one transformer per publisher), not a single transformer with many outputs.
list_creative_formats discovery filters → list_transformers
Stop filtering list_creative_formats on input_format_ids / output_format_ids to find “what can build X”. Use list_transformers — filter on its input_format_ids / output_format_ids, narrow with brief, and expand account-scoped option values with expand_params.
What breaks silently if you do nothing
These do not throw — which is exactly why they are the reason this guide exists.-
Discovery-read degradation (buyers). If your buyer/storyboard learns build capability only by reading
Format.input_format_ids/output_format_idsor by filteringlist_creative_formatson them, you keep working against a 3.1 seller but see progressively emptier results as sellers stop emitting the deprecated fields and move capability onto transformers. No error — just fewer and fewer options. The field outlives its data. Move discovery tolist_transformers. -
Per-output pricing loss (multi-publisher template sellers). See the pricing note above — a template that priced outputs differently silently mis-states pricing after a naïve
Format.pricing_options→transformer.pricing_optionslift. Split into per-price-point transformers. -
Fan-out / best-of-N spend under-counting (billing pipelines). With
max_variants/max_creatives, every produced variant is billed, but only a trafficked leaf lazily earns acreative_id. Discarded best-of-N leaves are billed via the inline per-leafvendor_coston thebuild_creativeresponse only — they never earn acreative_idand so never appear inreport_usage. A pipeline that reconciles spend solely fromreport_usage(the 3.0 invariant “every billed unit reconciles viacreative_id”) will under-count by every discarded variant. Ingest the inline per-leaf receipts as the authoritative record for untrafficked leaves.
SDK behavior and timeline
| Version | Deprecated fields |
|---|---|
| 3.1 | deprecated: true; still emitted and honored. SDKs MUST continue to read them. |
| 3.1–3.x | Honored throughout. New code SHOULD NOT emit them. |
| 4.0+ | SDKs MAY reject. Removed. |
See also
list_transformers— discover transformers, their params, option values, and pricingbuild_creative— select a transformer, configure, multiply, refine- What’s new in 3.1