> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Creative Specification

> The AdCP Creative Protocol specification defines format discovery, manifest validation, AI creative generation, and preview rendering.

<Info>
  **AdCP 3.2:** canonical declarations are the current Creative Protocol model. Named format IDs and `list_creative_formats` are deprecated compatibility surfaces. Fields named exactly `format_ids` are removed in AdCP 4.0; singular `format_id`, named-format definitions, and the task follow separate schedules.
</Info>

**Status**: Current specification
**Last Updated**: July 2026

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).

## Abstract

The Creative Protocol defines a standard interface for creative format discovery, manifest validation, creative generation, and preview rendering. This protocol enables AI agents to discover format specifications, build compliant creative assets, and generate previews across advertising platforms.

## Protocol overview

The Creative Protocol provides:

* Format discovery with full technical specifications
* Manifest validation against format requirements
* AI-powered creative generation and transformation
* Preview rendering for creative verification
* Universal macros for cross-platform tracking

## Transport requirements

Creative agents MUST support at least one of the following transports:

| Transport | Protocol               | Description                         |
| --------- | ---------------------- | ----------------------------------- |
| MCP       | Model Context Protocol | Tool-based interaction via JSON-RPC |
| A2A       | Agent-to-Agent         | Message-based interaction           |

Creative agents SHOULD support MCP as the preferred transport.

Creative agents MUST declare Creative Protocol support via `get_adcp_capabilities`:

```json theme={null}
{
  "$schema": "https://adcontextprotocol.org/schemas/3.2.0-beta.0/protocol/get-adcp-capabilities-response.json",
  "status": "completed",
  "adcp": {
    "major_versions": [2],
    "idempotency": { "supported": true, "replay_ttl_seconds": 86400 }
  },
  "supported_protocols": ["creative"],
  "creative": {
    "has_creative_library": true,
    "supports_generation": false,
    "supports_transformation": true,
    "supports_compliance": false,
    "supported_formats": [
      {
        "capability_id": "display_image_transform",
        "operations": ["build", "validate", "preview"],
        "format": {
          "format_kind": "image",
          "params": { "width": 300, "height": 250 }
        }
      }
    ]
  }
}
```

The `creative` capabilities tell the buyer which interaction models this agent supports. See [Interaction models](#interaction-models) below.

## Core concepts

### Creative agents

A creative agent is any agent that implements the Creative Protocol. This includes standalone services (ad servers, creative management platforms, generative tools) and sales agents that declare `"creative"` in `supported_protocols`. A creative agent:

* Defines and documents formats it owns
* Validates manifests against format requirements
* Generates previews showing how creatives will render
* Optionally generates or transforms creatives from natural language briefs

Sales agents that implement both the Media Buy Protocol and the Creative Protocol serve both roles from a single endpoint. See [Creative capabilities on sales agents](/dist/docs/3.2.0-beta.0/creative/sales-agent-creative-capabilities).

### Interaction models

Creative agents serve different roles depending on their capabilities. Buyers use `get_adcp_capabilities` to determine which interaction model applies:

| Model                    | Description                                         | Capabilities                    | Examples                    |
| ------------------------ | --------------------------------------------------- | ------------------------------- | --------------------------- |
| **Transformation agent** | Resizes or adapts existing manifests to new formats | `supports_transformation: true` | Format conversion services  |
| **Generative agent**     | Creates manifests from natural language briefs      | `supports_generation: true`     | AI creative platforms       |
| **Creative ad server**   | Hosts a creative library, generates ad-serving tags | `has_creative_library: true`    | Flashtalking, CM360, Celtra |

These models compose — an agent can support multiple. A creative ad server with `supports_generation: true` and `has_creative_library: true` can both generate creatives from briefs and retrieve existing ones from its library. The `supports_compliance` flag is orthogonal — any interaction model can support compliance requirements in briefs.

**Buyer workflow by model:**

* **Transformation**: `get_adcp_capabilities` → choose `creative.supported_formats[].capability_id` → `build_creative` with `creative_manifest` + `target_capability_id`
* **Generation**: `get_adcp_capabilities` → choose a build capability → `build_creative` with `message` + `target_capability_id`
* **Library retrieval**: `list_creatives` → `build_creative` with `creative_id` + `target_capability_id`

Agents that host a creative library should also implement the [accounts protocol](/dist/docs/3.2.0-beta.0/accounts/overview) so buyers can establish access before querying. Sales agents that already implement accounts for media buys do not need to do anything additional.

A transformation or generation agent that charges for its services implements the Accounts Protocol, exposes account-scoped pricing through `list_transformers`, and returns applied pricing in `build_creative` responses. Agents that persist `creative_id` on build output can also expose pricing on `list_creatives`. Free transformation agents remain stateless and unchanged.

### Format authority and creative capability

Canonical format authority is contextual. Publishers own the acceptance declarations in `adagents.json.formats[]`; sales agents own each product's deliverable `format_options[]`; creative agents own claims about what they can build, validate, or preview in `creative.supported_formats[]`.

A creative agent claiming exact support for a publisher format repeats its `{publisher_domain, format_option_id}` identity inside the capability's canonical `format` declaration. A generic capability omits publisher identity and matches only when its parameter envelope can satisfy every target constraint.

### Formats

Formats define how assets are assembled and rendered. A format specifies:

* Media family (display, video, audio, dooh)
* Required and optional asset types
* Technical constraints (dimensions, duration, file size, codecs)
* Rendering behavior and interaction expectations

### Assets

Assets are the building blocks of creatives. Asset types include:

* **image**: Static images (JPEG, PNG, WebP, GIF)
* **video**: Video files (MP4, WebM, MOV) or VAST tags
* **audio**: Audio files (MP3, M4A) or DAAST tags
* **text**: Headlines, descriptions, CTAs
* **html**: HTML5 creatives or third-party tags
* **javascript**: JavaScript tags
* **url**: Tracking pixels, clickthrough URLs

### Manifests

Manifests pair canonical format specifications with actual asset content. A manifest provides:

* Canonical `format_kind` and optional product/publisher `format_option_ref`
* Asset values keyed by canonical slot name
* Tracking URLs and macros

Creative agents MUST validate manifests against format requirements before accepting them.

### Native creative localization

Native localization is a library/trafficking capability, distinct from
`build_creative` fan-out and from served delivery variants. An agent supports
it only when `get_adcp_capabilities.creative.localization` is present. This is
a coarse structural capability: it advertises materialized locale variants,
RFC 4647 Lookup, and an optional target-variant ceiling, not universal support
for every locale, format, or account. Because exact `list_creatives` readback
is part of the contract, advertising localization also requires
`creative.has_creative_library: true`.

This section implements the executable-creative pattern from the
[cross-protocol language and localization architecture](/dist/docs/3.2.0-beta.0/protocol/language-and-localization).
Other language-bearing surfaces reuse the tag and matching primitives without
inheriting creative variant topology.

`sync_creatives.creatives[].localization` carries only materialized assets. It
never asks the receiving seller to translate or generate creative. A buyer may
produce those assets itself, through `build_creative`, or through a separate
translation/transformation agent before sync; their production provenance does
not change this trafficking contract. This is the only localization write
surface. Inline creatives on
`create_media_buy` and `update_media_buy` reject `localization`; buyers first
sync the localized library creative and then assign it to a package.

* The creative's top-level `assets` are the source variant.
* `localization.source` binds those assets to a canonical BCP 47 tag and a
  buyer-assigned `locale_variant_id`.
* `target_variants[]` may be empty for a monolingual source-only creative.
  Every target entry has a unique locale and stable
  `locale_variant_id` plus locale-specific materialized asset overrides;
  missing slots inherit source assets.
* `default_locale_variant_id` explicitly identifies the serving fallback. It
  may reference the source or a target; source does not imply default.
* `locale_fallbacks[]` optionally maps a canonical requested language range to
  a source or target variant. These are explicit buyer-approved substitutions,
  not inferred equivalence between regional variants.
* `unmatched_locale_action` is `serve_default` or `do_not_serve`.

In this contract, `locale` is a BCP 47 language tag used only for language
identity. Script and region may refine that identity; other valid subtags remain
part of tag matching but do not make this a general locale-settings object. It
does not determine currency, time zone, number/date formatting, market, or legal
jurisdiction; those require their own fields and policies.

AdCP defines a canonical wire profile for those tags: lower-case language and
variants, title-case script, and upper-case region (for example `en-US` and
`zh-Hant-TW`). This is intentionally stricter than
[RFC 5646](https://www.rfc-editor.org/rfc/rfc5646), where tags compare
case-insensitively and case regularization is optional. A receiver MUST reject
malformed, duplicate, non-profile, unsupported, or lossily mapped tags rather
than silently normalizing them or mutating seller systems or the creative
library.

Within a localized creative, `language` on `text` and `markdown` assets is
optional. When present, it is an explicit content-language claim: it MUST use
the shared tag schema and exactly equal the enclosing variant's `locale` after
source inheritance. Omit it for an asset that makes no independent language
claim. This contextual rule avoids tightening legacy non-localized asset
payloads while preventing contradictory metadata such as an `es-ES` variant
containing a text asset labeled `en-US`.

`brand.json` localized name/tagline keys are a deliberate legacy boundary:
values such as `en_US` use underscore notation and are not valid values of the
shared tag schema. A bridge into creative localization replaces `_` with `-`,
applies the AdCP canonical wire profile, and validates the result; it MUST NOT
copy the legacy key unchanged. The current brand schema retains that syntax for
compatibility pending a separately versioned migration.

After source inheritance, each fully resolved variant MUST satisfy the selected
creative format.

A selected product `format_options[]` declaration may additionally carry
`locale_policy.accepted_language_ranges`. Seller ranges use RFC 4647 Basic
Filtering, so `fr` accepts `fr-CA` and `fr-FR`; this is intentionally different
from the buyer's strict delivery Lookup. The seller first filters the creative
to variants eligible for each effective product-and-placement format option
where the assignment may serve,
then applies the buyer's matching rules only within that set. Assignment fails
with `CREATIVE_LOCALE_NOT_ACCEPTED` when no variant is eligible, or when
`serve_default` references an ineligible default. Nonmatching variants remain
part of the reusable creative but cannot serve on that assignment.

At delivery, sellers apply RFC 4647 Lookup to the opportunity's ordered locale
preferences and the creative's seller-eligible locale tags. Lookup progressively
truncates the requested range until it finds an available canonical tag equal
to that range. Matching is equality, not prefix/subordination: `es-MX` does not
match an available `es-ES` after truncation to `es`.

That ordered preference list is an external input from the seller's serving
environment; it is not carried by this contract. AdCP does not standardize how
browser or app preferences, page/content language, geography, user settings,
or platform settings produce the list or their precedence. Once the seller has
an ordered list, AdCP standardizes only the deterministic filtering, Lookup,
explicit fallback, and unmatched behavior described here.

For each preference in order, if strict Lookup finds no equality match, the
seller repeats the same most-specific-to-least-specific truncation against
`locale_fallbacks[].language_range` and serves the referenced variant from the
first matching rule. For example, `language_range: es` may explicitly map both
`es-ES` and `es` preferences to an available `es-MX` variant. The seller tries
the next preference only when neither strict Lookup nor an explicit rule
matches the current preference. After every preference misses, the seller MUST
apply `unmatched_locale_action`; it MUST NOT infer regional interchangeability
or silently substitute the source.
Every delivered execution of a localized creative includes the selected
`locale_variant_id` in `get_creative_delivery`, including explicit and default
fallback.

`locale_variant_id` is scoped to the parent creative. It is not a
`build_variant_id` (a `build_creative` output leaf) and not the `variant_id`
used for a seller's served execution in `get_creative_delivery`. A successful
localized sync and every later `list_creatives` read MUST preserve the exact
source ID/locale, target ID/locale set, default ID, and unmatched action from
the request, plus the exact optional fallback-rule set. Readback returns fully
resolved assets under those same buyer-assigned `locale_variant_id` values; it
does not add a separate seller- or platform-assigned variant identity.

Localized readback is atomic. The seller returns complete resolved assets,
buyer-assigned variant identities, default policy, and matching mode for the
source and every target. Review remains creative-wide: the enclosing creative's
single `status` applies to the complete locale set and normal
`creative.status_changed` webhooks report its changes. If exact localization
evidence is unavailable, `list_creatives` returns `localization_unavailable`
for that creative instead of omitting a locale or returning a partial object.
The item remains in the page and pagination counts; buyers MUST NOT infer locale
eligibility from the base creative fields.

On upsert, a non-null `localization` object replaces the creative's complete
locale set and top-level source assets transactionally; failure leaves the
prior source assets and complete localization state unchanged, and orphaned
locale variants MUST NOT become visible. `localization: null` removes the
locale topology. Omission preserves existing localization only when top-level
source assets exactly equal the prior source assets. `delete_missing` still
operates only at creative scope.

Capabilities govern new writes, not stored-data readability or already accepted
assignment terms. The seller snapshots the effective product-and-placement
locale policy when it accepts an assignment. Later catalog policy changes apply
only to new or changed assignments; the seller MUST NOT silently rewrite or
remove an existing buyer-managed assignment. If a seller later withdraws
localization support, it MUST keep existing localized creatives readable and
honor each accepted assignment policy until that assignment changes or its
media buy terminates. A creative-wide dependency loss that makes the approved
creative unsafe everywhere moves the whole creative to `suspended` and uses
the normal lifecycle webhook. Sellers may reject new or replacement
localization, but MUST still allow explicit `localization: null` cleanup when it
does not violate an active assignment.

### Universal macros

AdCP defines universal macros for cross-platform tracking. Creative agents MUST support these macros in tracking URLs:

* `{TIMESTAMP}`: Unix timestamp
* `{CACHEBUSTER}`: Random cache-busting value
* `{CLICK_URL}`: Click tracking URL
* `{REDIRECT_URL}`: Final destination URL

Sales agents MUST translate universal macros to their ad server's native syntax.

## Creative Status Lifecycle

**Schema**: [`enums/creative-status.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/enums/creative-status.json)

Creatives in a library progress through a defined set of states. Most transitions are seller-initiated (processing, review, approval/rejection). `suspended` is a recoverable offline state for approved creatives whose dependencies become unavailable, such as an expired published-post authorization. `archived` is reached either by buyer cleanup or by seller-side lifecycle policy on creatives without active assignments — see the rules below.

```
sync_creatives ──▶ processing ──▶ pending_review ──▶ approved
                       │                 │              │
                       │                 │              ├──▶ suspended ──▶ approved
                       │                 │              │        │
                       │                 │              │        └──▶ rejected
                       │                 │              ├──▶ pending_review
                       │                 │              ├──▶ rejected
                       │                 │              └──▶ archived
                       │                 │
                       └──────▶ rejected ◀──────────────┘
                                  │
                                  └── buyer fixes + resubmits ──▶ processing

archived ── buyer unarchives ──▶ approved (or pending_review when re-review is required)
```

**Rules:**

* `processing` → `pending_review`: automatic when ingestion and transcoding succeed
* `processing` → `rejected`: automatic when processing fails (corrupt file, unsupported codec, constraint violation)
* `pending_review` → `approved`: seller approves after content policy review
* `pending_review` → `rejected`: seller rejects with `rejection_reason`
* `approved` → `suspended`: seller detects a recoverable dependency/authorization loss, such as `identity_authorization_revoked`, `identity_authorization_expired`, or `source_private` for a `published_post` reference. Sellers MUST surface a corresponding `impairment` on affected active buys.
* `suspended` → `approved`: seller observes that the dependency is restored and any required re-review passes.
* `suspended` → `rejected`: seller determines that a previously recoverable dependency/authorization loss cannot be restored for this creative, or that replacement/resubmission is required. Example: a revoked identity/post authorization for a `published_post` reference cannot be reauthorized. Sellers MUST keep affected active buys impaired until the creative is replaced, reassigned, or the package/buy is otherwise remediated.
* `approved` → `archived` (buyer-initiated): buyer issues archive via `sync_creatives`
* `approved` → `archived` (seller-initiated): seller archives an unassigned creative for inactivity, post-flight expiry, or storage policy. Sellers MUST NOT seller-archive a creative that has active package assignments — the `approved` → `rejected` (revocation) path with an `impairment` on the affected buy is the only conformant route when active serving is involved. State-change observability for seller-initiated archive follows the [creative retention contract](/dist/docs/3.2.0-beta.0/creative/creative-libraries#creatives-outlast-campaigns) — minimally, the new `status` MUST be visible on the next `list_creatives` read.
* `archived` → `approved`: buyer-initiated via `sync_creatives` (unarchive). Sellers MAY require re-review, transitioning to `pending_review` instead.
* `rejected` → `processing`: buyer fixes the creative and resubmits via `sync_creatives`. The creative re-enters the full processing and review pipeline.
* `approved` → `pending_review`: seller-initiated re-review (e.g., policy change). Sellers MUST notify subscribers via `creative.status_changed` (fired to each `notification_configs[]` subscriber whose `event_types[]` includes this value — see below) when a previously approved creative is pulled back for re-review.

Creative agents MUST reject operations that reference a `rejected` creative for delivery (e.g., assigning it to a package) with error code `CREATIVE_REJECTED`. Creative agents MUST also prevent delivery of `suspended` creatives until the dependency is restored.

Creative agents MUST include `status` and `rejection_reason` (when rejected) in `list_creatives` responses.

### Lifecycle webhooks

Seller-initiated and system-initiated transitions fire push notifications against the account's [`notification_configs[]`](/dist/docs/3.2.0-beta.0/accounts/tasks/sync_accounts#account-level-webhook-subscriptions) subscribers — each entry whose `event_types[]` includes the fired type receives an independent fire. Two event types cover the surface:

* **`creative.status_changed`** — fires on every seller-initiated or system-initiated transition: `pending_review → approved`/`rejected`, `approved → pending_review` (re-review), `approved → suspended` (recoverable dependency/authorization loss), `suspended → approved` (recovery), `suspended → rejected` (terminal dependency/authorization loss), `approved → rejected` (post-approval revocation), `approved → archived` (seller-initiated). Payload: [`creative-status-changed-webhook.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/creative-status-changed-webhook.json).
* **`creative.purged`** — fires when a creative is destroyed (retention sweep, takedown, legal erasure). `soft` purges retain a tombstone on `list_creatives` (with `include_purged: true`) for 30 days; `hard` purges retain no record — the webhook is the buyer's only signal. Payload: [`creative-purged-webhook.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/creative-purged-webhook.json).

Buyer-initiated transitions (archive, unarchive, resubmit) do NOT fire — those are acknowledged on the `sync_creatives` response path. The push channel exists only for transitions the buyer did not initiate.

Both events carry a categorical `reason_code` drawn from [`creative-event-reason-code.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/enums/creative-event-reason-code.json). Buyer-side remediation per reason code is documented inline on the enum's `enumDescriptions`.

When a creative transitions to a state that breaks active serving (`approved → suspended`, `approved → rejected`, `suspended → rejected`, or seller-initiated `approved → archived` while assignments exist — which is non-conformant; see the transition rules above), the seller MUST also surface a corresponding `impairment` on every media buy referencing the creative (see [Media buy health](/dist/docs/3.2.0-beta.0/media-buy/media-buys/lifecycle#health-and-impairments)). The creative-side `creative.status_changed` and the buy-side `impairment` are paired but distinct signals; buyers correlate by `creative_id`. The two surfaces have different anchors: creative events fire account-level (subscriptions outlive any one buy); impairments fire per-buy. **No ordering guarantee** between the paired fires — buyers MUST NOT assume one arrives before the other; reconcile via the snapshot (`list_creatives` and `get_media_buys`).

Sellers declare which event types they support and per-type coalescence windows via `get_adcp_capabilities`. Default coalescence is 5 minutes for `creative.status_changed`; sellers MUST NOT coalesce `creative.purged`. Retroactive contract: when a seller declares support for these event types, the obligation covers all creatives in the library — no grace period for pre-existing creatives.

Buyers MAY pull recent webhook fires per creative via `list_creatives` with `include_webhook_activity: true`. The read surface follows the [`webhook_activity[]` adoption checklist](/dist/docs/3.2.0-beta.0/protocol/snapshot-and-log#webhook-activity-log-pattern) — 30-day retention, three-state presence semantics, `idempotency_key` correlation to buyer-side endpoint logs.

## Pricing

Creative agents that charge for their services expose pricing through the same discover → build → report loop used by signals agents and content standards agents.

### Pricing discovery surfaces

Pricing is discovered via two surfaces depending on the agent's interaction model:

* **`list_creatives`** — ad servers and library-based agents expose `pricing_options[]` on each creative. The buyer discovers pricing for specific creatives they want to use.
* **`list_transformers`** — transformation and generation agents expose account-scoped `pricing_options[]` and canonical `output_capability_ids` on selectable transformers.

Both surfaces use the same `pricing_options[]` array of [`vendor-pricing-option`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/vendor-pricing-option.json) objects. Both require `account` and `include_pricing: true` on the request.

An agent MAY expose pricing on both surfaces (e.g., a creative management platform that has both a library and transformation capabilities).

### Pricing flow

1. **Account setup** — rate card agreed. Determines pricing for all subsequent operations.
2. **Discovery** — `list_creatives` or `list_transformers` with `account` and `include_pricing: true` returns `pricing_options[]`. Vendors may offer multiple options.
3. **Build** — `build_creative` with `account`. The agent computes the cost and returns `pricing_option_id`, `vendor_cost`, `currency`, and `consumption` in the response.
4. **Report** — `report_usage` with `creative_id` and `pricing_option_id` for reconciliation.

### Pricing models

Creative agents reuse the vendor pricing models defined in [`vendor-pricing-option.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/vendor-pricing-option.json):

| Model              | Creative use case                                                                                       |
| ------------------ | ------------------------------------------------------------------------------------------------------- |
| `cpm`              | Cost per thousand impressions served — ad server model, DCO platforms                                   |
| `percent_of_media` | Percentage of media spend — agency/platform model                                                       |
| `flat_fee`         | Fixed charge per period — licensed creative suites, subscription access                                 |
| `per_unit`         | Fixed price per unit of work — per format adapted, per image generated, per token, per variant rendered |

### Consumption details

**Schema**: [`core/creative-consumption.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/creative-consumption.json)

The `build_creative` response includes a `consumption` object with structured details about what was consumed. Well-known fields: `tokens` (LLM tokens consumed), `images_generated`, `renders` (render passes), `duration_seconds` (processing time). Agents MAY include additional fields.

The `consumption` object is informational — it lets the buyer verify that `vendor_cost` is consistent with the rate card. `vendor_cost` is the billing source of truth.

### Accounts requirement

Creative agents that charge for their services MUST implement the [Accounts Protocol](/dist/docs/3.2.0-beta.0/accounts/overview). This applies to any creative agent with pricing — ad servers, generation platforms, and transformation agents that bill for usage.

### Bundled mode

When a publisher uses a creative agent internally (bundled), the buyer never sees the creative agent's pricing. The cost is absorbed into product pricing. The sales agent is the buyer in the creative agent relationship — it establishes an account, calls `build_creative`, and handles `report_usage`. The protocol surface is the same.

## Tasks

The Creative Protocol defines the following tasks. See task reference pages for complete request/response schemas and examples.

### get\_adcp\_capabilities

**Reference**: [`get_adcp_capabilities`](/dist/docs/3.2.0-beta.0/protocol/get_adcp_capabilities)

Discover canonical creative operations and their format contracts through `creative.supported_formats[]`.

**Requirements:**

* Every entry MUST carry a canonical `format` declaration; new 3.2 producers MUST also carry a stable `capability_id`
* Exact publisher-format claims MUST carry `{publisher_domain, format_option_id}`
* Generic capabilities MUST declare an honest parameter envelope
* New 3.2 producers MUST carry explicit `operations` to distinguish build, validation, and preview support. Consumers interpret omission on legacy 3.x entries as `build`.

`list_creative_formats` is deprecated in 3.2 and retained only for legacy named-format compatibility.

### list\_transformers

**Reference**: [`list_transformers` task](/dist/docs/3.2.0-beta.0/creative/task-reference/list_transformers)

Discover the account-scoped transformers a creative agent offers — the creative analog of media-buy products: agent-offered, selectable units of build capability (voices, models, styles) that you select with `transformer_id` in `build_creative`. Offered only by agents that declare `creative.supports_transformers: true` in `get_adcp_capabilities`.

**Requirements:**

* Creative agents that set `creative.supports_transformers: true` MUST implement `list_transformers`
* Creative agents MUST resolve transformers, their enumerable option values, and pricing for the calling account — including custom values configured for that account (e.g. cloned voices)
* Creative agents MUST return account-scoped option values inline on `params[].options[]` for each `field` named in `expand_params`, and SHOULD omit them otherwise
* When `include_pricing` is true, creative agents that charge MUST include `pricing_options` (the `per_unit` model) on each transformer

### build\_creative

**Reference**: [`build_creative` task](/dist/docs/3.2.0-beta.0/creative/task-reference/build_creative)

Transform, generate, or retrieve creative manifests. Supports three modes:

1. **Generation**: Create a manifest from a brief or seed assets
2. **Transformation**: Adapt an existing manifest to a different format
3. **Library retrieval**: Resolve a `creative_id` from the agent's library into a manifest with ad-serving assets (HTML/JavaScript/VAST tags)

**Requirements:**

* Creative agents MUST validate input manifests against format requirements
* Creative agents MUST return a valid manifest for the target format on success
* Creative agents MUST return validation errors if the transformation cannot be completed
* Creative agents SHOULD preserve tracking URLs and macros during transformation
* Creative agents SHOULD respect `quality` for generative tasks (`"draft"` for fast iteration, `"production"` for final delivery) and MAY ignore it for non-generative transforms
* Creative agents SHOULD honor `item_limit` when present, using the lesser of `item_limit` and the format's `max_items`
* Creative agents MAY use AI/LLM processing for generation tasks
* When `creative_id` is provided, creative agents MUST resolve the creative from their library
* When `macro_values` is provided, creative agents SHOULD substitute the specified macros in the output manifest's assets and leave unresolved macros as `{MACRO}` placeholders
* Creative agents MUST ignore unrecognized macro keys in `macro_values` — unknown macros are not an error
* Creative agents SHOULD assign globally unique `creative_id` values; when they cannot guarantee uniqueness, `concept_id` is REQUIRED on `build_creative` requests to disambiguate
* `build_creative` supports async responses (`status: "working"` with `context_id` polling) for generation and transformation tasks that take significant time. Library retrieval is typically synchronous.
* When `account` is provided and the agent charges, the response MUST include `pricing_option_id`, `vendor_cost`, and `currency`. The `consumption` object SHOULD be included when relevant.
* For async builds, pricing fields appear on the final completed response only, not on intermediate status responses.
* When a paid creative agent receives a `build_creative` request without `account` and the agent requires an account, the agent MUST return an error.

### preview\_creative

**Reference**: [`preview_creative` task](/dist/docs/3.2.0-beta.0/creative/task-reference/preview_creative)

Generate preview renderings of creative manifests.

**Requirements:**

* Creative agents MUST validate manifests before generating previews
* Creative agents MUST return preview URLs or HTML for valid manifests
* Creative agents MUST keep preview URLs dereferenceable until their `expires_at` timestamp. When `expires_at` is omitted, preview URLs do not expire at the protocol layer and remain valid until the agent explicitly revokes them out of band.
* Creative agents SHOULD include `expires_at` for time-limited preview URLs
* Creative agents SHOULD support batch preview for multiple creatives
* Creative agents MAY support multiple output formats (URL, HTML, image)

### list\_creatives

**Schema**: [`creative/list-creatives-request.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/list-creatives-request.json) / [`creative/list-creatives-response.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/list-creatives-response.json)

**Reference**: [`list_creatives` task](/dist/docs/3.2.0-beta.0/creative/task-reference/list_creatives)

Browse and filter creative assets in a creative library. Implemented by any agent that hosts a creative library — ad servers, creative management platforms, and sales agents that manage creatives.

**Requirements:**

* Agents MUST return creatives accessible to the authenticated account
* Agents MUST include approval status for each creative
* Agents SHOULD support filtering by format, status, tags, and date range
* Agents SHOULD support filtering by `concept_ids` and canonical `format_kinds` when the platform organizes creatives into concepts
* Agents MAY include dynamic content variable definitions when `include_variables=true`
* Agents MAY include a lightweight delivery snapshot when `include_snapshot=true`. The snapshot provides lifetime impressions and last-served date for operational use — detailed analytics belong in `get_creative_delivery`.
* Sales agents declaring `list_creatives` in `media_buy.relationship_notifications.projection_tasks` MUST scope creative indicators to `assignments.assigned_packages[].indicators[]`; they MUST NOT place package- or publisher-specific fatigue on the creative as a global property.
* Those sellers MUST include `media_buy_id` and `approval_status` on every assignment row, including rows whose indicator state is unknown. `rejection_reason` and `approval_scopes` mirror the media-buy projection. `indicator_types_evaluated` declares exact type coverage; `indicators_evaluated_scope` declares partial publisher/placement coverage.
* When the same relationship is visible through both reads, `media_buy_id`, `package_id`, `creative_id`, `approval_status`, `rejection_reason`, and `approval_scopes` MUST agree. Indicator timestamps and evaluation coverage SHOULD converge, but a later read MAY reflect a strictly newer evaluation; buyers reconcile toward the newer `indicators_as_of` rather than treating a legitimate reevaluation between calls as incoherence.
* Indicator polling is always available through `get_media_buys` when `supported_indicator_types` is declared. Sellers may additionally accept prospective `indicators.changed` and independently accept `creative.assignment_changed`, including when they are inline-only. Receivers of either event establish a complete all-status or known-ID baseline and repair through `get_media_buys` rather than treating payloads or the bounded reverse projection as complete relationship state.
* When `account` and `include_pricing=true` are provided, agents that charge MUST include `pricing_options` on each creative — an array of [`vendor-pricing-option`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/vendor-pricing-option.json) objects. Vendors may offer multiple options per creative (volume tiers, context-specific rates, different pricing models).

**Account requirements:**

* Creative agents that charge for their services MUST implement the [Accounts Protocol](/dist/docs/3.2.0-beta.0/accounts/overview). This applies to any creative agent with pricing — ad servers, generation platforms, and transformation agents that bill for usage.
* Creative agents that host a library but do not charge SHOULD implement the Accounts Protocol so buyers can establish access before querying.
* This is the same accounts protocol used by sales agents — there is no separate version.
* Sales agents that already implement accounts for media buys do not need to do anything additional.

### sync\_creatives

**Schema**: [`creative/sync-creatives-request.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/sync-creatives-request.json) / [`creative/sync-creatives-response.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/sync-creatives-response.json)

**Reference**: [`sync_creatives` task](/dist/docs/3.2.0-beta.0/creative/task-reference/sync_creatives)

Upload and synchronize creative assets in a library. Implemented by any agent that hosts a creative library — ad servers, creative management platforms, and sales agents that manage creatives.

**Requirements:**

* Agents MUST validate creatives against format specifications
* Agents MUST return validation errors for non-compliant creatives
* Agents MAY require approval before creatives are available for use
* Agents SHOULD support `dry_run` for validation without applying changes
* Agents MUST reject requests that combine `delete_missing: true` with `creative_ids` — `delete_missing` applies to the entire library, not a filtered subset
* Agents that advertise `creative.localization` MUST reject unsupported localization before mutation and return exact localization readback on every accepted localized creative
* Agents that also manage media buys SHOULD support the `assignments` field for bulk creative-to-package mapping
* Standalone creative agents that do not manage media buys SHOULD ignore the `assignments` field

### get\_creative\_delivery

**Reference**: [`get_creative_delivery` task](/dist/docs/3.2.0-beta.0/creative/task-reference/get_creative_delivery)

Retrieve creative delivery data with variant-level metrics.

**Requirements:**

* Agents MUST return delivery data for the requested creatives
* Agents SHOULD include variant-level breakdowns when available
* Sales agents implementing the Creative Protocol SHOULD support this task when their products generate or optimize creative variants

## Error handling

Creative agents MUST return errors using the [standard AdCP error schema](/dist/docs/3.2.0-beta.0/building/by-layer/L3/error-handling).

Common error codes:

* `FORMAT_NOT_SUPPORTED`: Requested creative capability does not exist or is not accessible (`error.field` identifies `target_capability_id` or the indexed plural field)
* `VALIDATION_ERROR`: Manifest failed format validation: a required asset is missing from the manifest, or an asset does not meet the format's constraints (`error.field` identifies the offending asset path)

Generation-pipeline failures (model or rendering errors during `build_creative`) surface as task-level failure (`status: "failed"`) with the most specific applicable code in `errors[]`. The error-code vocabulary is open: sellers MAY return platform-specific codes for failure modes the canonical enum does not cover, and agents MUST handle unknown codes by falling back to the recovery classification.

## Security considerations

### Transport security

All Creative Protocol communications MUST use HTTPS with TLS 1.2 or higher.

### Asset security

* Creative agents SHOULD validate that asset URLs are accessible
* Creative agents SHOULD scan assets for malware and malicious content
* Creative agents MUST NOT execute untrusted JavaScript during validation

### Preview security

* Preview URLs SHOULD be time-limited (indicated by `expires_at`)
* Preview URLs MUST NOT depend on pod-local or process-local state unless the agent can guarantee that state for the advertised lifetime of the URL
* Creative agents SHOULD sandbox HTML previews to prevent script execution
* Consumers of `output_format: "html"` MUST only use trusted creative agents

## Conformance

### Creative agent conformance

A conformant Creative Protocol agent MUST:

1. Support at least one specified transport (MCP or A2A)
2. Implement `get_adcp_capabilities` and publish canonical `creative.supported_formats[]`
3. Give every supported-format entry a stable `capability_id` and accurate operations
4. Validate manifests against format specifications
5. Use specified error codes

A conformant Creative Protocol agent SHOULD:

1. Implement `build_creative` for creative generation
2. Implement `preview_creative` for preview rendering
3. Support universal macros in tracking URLs
4. Implement `list_creatives` when the agent hosts a creative library
5. Implement `sync_creatives` when the agent accepts creative uploads
6. Support `creative_id` in `build_creative` when the agent hosts a creative library
7. Implement the accounts protocol (`sync_accounts` / `list_accounts`) when hosting a creative library
8. Declare `supports_generation`, `supports_transformation`, and `has_creative_library` in `get_adcp_capabilities` so buyers can determine the correct interaction model

### Consumer conformance

A conformant Creative Protocol consumer MUST:

1. Discover creative operations through `creative.supported_formats[]` and route builds with `target_capability_id(s)`
2. Validate manifests against format specifications before submission
3. Handle validation errors appropriately
4. Confirm the selected registry candidate directly with `get_adcp_capabilities`

## Implementation notes

### Response time expectations

Creative agents SHOULD target the following response times:

| Operation Type                                 | Target Latency |
| ---------------------------------------------- | -------------- |
| Capability discovery (`get_adcp_capabilities`) | \< 1 second    |
| Library query (list\_creatives)                | \< 1 second    |
| Creative sync (sync\_creatives)                | \< 5 seconds   |
| Preview generation (preview\_creative)         | \< 5 seconds   |
| Batch preview (10 creatives)                   | \< 10 seconds  |
| Creative generation (build\_creative)          | \< 60 seconds  |

### Creative-agent discovery

Use the AgenticAdvertising.org registry to reverse-match `creative.supported_formats[]` by canonical kind or exact `{publisher_domain, format_option_id}`. Creative agents do not recursively nominate other creative agents.

### Format-aware validation

Manifest validation MUST be performed in the context of the format specification:

1. Resolve the selected canonical product/publisher declaration
2. For each manifest asset, find the corresponding declared slot
3. Validate its explicit `asset_type` discriminator and constraints against that slot

Every canonical asset includes its own `asset_type`; slot lookup supplies the permitted role and narrowing constraints.

### Standard vs custom formats

* **Canonical formats**: Registered AdCP `format_kind` contracts shared across publishers, sellers, and creative agents
* **Custom formats**: `format_kind: "custom"` plus a recognized `format_shape` and digest-pinned `format_schema`

Both use the same canonical declaration and constraint-matching rules. Publisher identity and creative-agent endpoint identity remain separate.

## Schema reference

<Note>
  Some creative protocol schemas (`build_creative`, deprecated `list_creative_formats`, `preview_creative`) have paths under `media-buy/` because they were originally released as part of the media-buy protocol. The schema paths remain stable compatibility identifiers.
</Note>

| Schema                                                                                                                                              | Description                                    |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| [`core/format.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/format.json)                                                           | Format definition                              |
| [`core/creative-manifest.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/creative-manifest.json)                                     | Creative manifest                              |
| [`core/creative-asset.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/core/creative-asset.json)                                           | Asset definition                               |
| [`media-buy/list-creative-formats-request.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/media-buy/list-creative-formats-request.json)   | Deprecated named-format compatibility request  |
| [`media-buy/list-creative-formats-response.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/media-buy/list-creative-formats-response.json) | Deprecated named-format compatibility response |
| [`creative/list-creatives-request.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/list-creatives-request.json)                   | list\_creatives request                        |
| [`creative/list-creatives-response.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/list-creatives-response.json)                 | list\_creatives response                       |
| [`creative/sync-creatives-request.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/sync-creatives-request.json)                   | sync\_creatives request                        |
| [`creative/sync-creatives-response.json`](https://adcontextprotocol.org/schemas/3.2.0-beta.0/creative/sync-creatives-response.json)                 | sync\_creatives response                       |
