Skip to main content
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.
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.

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: Creative agents SHOULD support MCP as the preferred transport. Creative agents MUST declare Creative Protocol support via get_adcp_capabilities:
The creative capabilities tell the buyer which interaction models this agent supports. See 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.

Interaction models

Creative agents serve different roles depending on their capabilities. Buyers use get_adcp_capabilities to determine which interaction model applies: 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_idbuild_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_creativesbuild_creative with creative_id + target_capability_id
Agents that host a creative library should also implement the accounts protocol 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. 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, 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 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.
Rules:
  • processingpending_review: automatic when ingestion and transcoding succeed
  • processingrejected: automatic when processing fails (corrupt file, unsupported codec, constraint violation)
  • pending_reviewapproved: seller approves after content policy review
  • pending_reviewrejected: seller rejects with rejection_reason
  • approvedsuspended: 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.
  • suspendedapproved: seller observes that the dependency is restored and any required re-review passes.
  • suspendedrejected: 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.
  • approvedarchived (buyer-initiated): buyer issues archive via sync_creatives
  • approvedarchived (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 approvedrejected (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 — minimally, the new status MUST be visible on the next list_creatives read.
  • archivedapproved: buyer-initiated via sync_creatives (unarchive). Sellers MAY require re-review, transitioning to pending_review instead.
  • rejectedprocessing: buyer fixes the creative and resubmits via sync_creatives. The creative re-enters the full processing and review pipeline.
  • approvedpending_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[] 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.
  • 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.
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. 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). 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 — 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 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. Discoverylist_creatives or list_transformers with account and include_pricing: true returns pricing_options[]. Vendors may offer multiple options.
  3. Buildbuild_creative with account. The agent computes the cost and returns pricing_option_id, vendor_cost, currency, and consumption in the response.
  4. Reportreport_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:

Consumption details

Schema: 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. 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 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 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 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 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 / creative/list-creatives-response.json Reference: list_creatives task 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 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. 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 / creative/sync-creatives-response.json Reference: sync_creatives task 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_idsdelete_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 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. 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:

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

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.