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.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:
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
Interaction models
Creative agents serve different roles depending on their capabilities. Buyers useget_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→ choosecreative.supported_formats[].capability_id→build_creativewithcreative_manifest+target_capability_id - Generation:
get_adcp_capabilities→ choose a build capability →build_creativewithmessage+target_capability_id - Library retrieval:
list_creatives→build_creativewithcreative_id+target_capability_id
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 inadagents.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_kindand optional product/publisherformat_option_ref - Asset values keyed by canonical slot name
- Tracking URLs and macros
Native creative localization
Native localization is a library/trafficking capability, distinct frombuild_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
assetsare the source variant. localization.sourcebinds those assets to a canonical BCP 47 tag and a buyer-assignedlocale_variant_id.target_variants[]may be empty for a monolingual source-only creative. Every target entry has a unique locale and stablelocale_variant_idplus locale-specific materialized asset overrides; missing slots inherit source assets.default_locale_variant_idexplicitly 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_actionisserve_defaultordo_not_serve.
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
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.
processing→pending_review: automatic when ingestion and transcoding succeedprocessing→rejected: automatic when processing fails (corrupt file, unsupported codec, constraint violation)pending_review→approved: seller approves after content policy reviewpending_review→rejected: seller rejects withrejection_reasonapproved→suspended: seller detects a recoverable dependency/authorization loss, such asidentity_authorization_revoked,identity_authorization_expired, orsource_privatefor apublished_postreference. Sellers MUST surface a correspondingimpairmenton 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 apublished_postreference 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 viasync_creativesapproved→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 — theapproved→rejected(revocation) path with animpairmenton 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 newstatusMUST be visible on the nextlist_creativesread.archived→approved: buyer-initiated viasync_creatives(unarchive). Sellers MAY require re-review, transitioning topending_reviewinstead.rejected→processing: buyer fixes the creative and resubmits viasync_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 viacreative.status_changed(fired to eachnotification_configs[]subscriber whoseevent_types[]includes this value — see below) when a previously approved creative is pulled back for re-review.
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’snotification_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).softpurges retain a tombstone onlist_creatives(withinclude_purged: true) for 30 days;hardpurges retain no record — the webhook is the buyer’s only signal. Payload:creative-purged-webhook.json.
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 exposepricing_options[]on each creative. The buyer discovers pricing for specific creatives they want to use.list_transformers— transformation and generation agents expose account-scopedpricing_options[]and canonicaloutput_capability_idson selectable transformers.
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
- Account setup — rate card agreed. Determines pricing for all subsequent operations.
- Discovery —
list_creativesorlist_transformerswithaccountandinclude_pricing: truereturnspricing_options[]. Vendors may offer multiple options. - Build —
build_creativewithaccount. The agent computes the cost and returnspricing_option_id,vendor_cost,currency, andconsumptionin the response. - Report —
report_usagewithcreative_idandpricing_option_idfor reconciliation.
Pricing models
Creative agents reuse the vendor pricing models defined invendor-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, callsbuild_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
formatdeclaration; new 3.2 producers MUST also carry a stablecapability_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
operationsto distinguish build, validation, and preview support. Consumers interpret omission on legacy 3.x entries asbuild.
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: trueMUST implementlist_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 eachfieldnamed inexpand_params, and SHOULD omit them otherwise - When
include_pricingis true, creative agents that charge MUST includepricing_options(theper_unitmodel) on each transformer
build_creative
Reference:build_creative task
Transform, generate, or retrieve creative manifests. Supports three modes:
- Generation: Create a manifest from a brief or seed assets
- Transformation: Adapt an existing manifest to a different format
- Library retrieval: Resolve a
creative_idfrom the agent’s library into a manifest with ad-serving assets (HTML/JavaScript/VAST tags)
- 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
qualityfor generative tasks ("draft"for fast iteration,"production"for final delivery) and MAY ignore it for non-generative transforms - Creative agents SHOULD honor
item_limitwhen present, using the lesser ofitem_limitand the format’smax_items - Creative agents MAY use AI/LLM processing for generation tasks
- When
creative_idis provided, creative agents MUST resolve the creative from their library - When
macro_valuesis 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_idvalues; when they cannot guarantee uniqueness,concept_idis REQUIRED onbuild_creativerequests to disambiguate build_creativesupports async responses (status: "working"withcontext_idpolling) for generation and transformation tasks that take significant time. Library retrieval is typically synchronous.- When
accountis provided and the agent charges, the response MUST includepricing_option_id,vendor_cost, andcurrency. Theconsumptionobject 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_creativerequest withoutaccountand 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_attimestamp. Whenexpires_atis 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_atfor 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_idsand canonicalformat_kindswhen 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 inget_creative_delivery. - Sales agents declaring
list_creativesinmedia_buy.relationship_notifications.projection_tasksMUST scope creative indicators toassignments.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_idandapproval_statuson every assignment row, including rows whose indicator state is unknown.rejection_reasonandapproval_scopesmirror the media-buy projection.indicator_types_evaluateddeclares exact type coverage;indicators_evaluated_scopedeclares partial publisher/placement coverage. - When the same relationship is visible through both reads,
media_buy_id,package_id,creative_id,approval_status,rejection_reason, andapproval_scopesMUST agree. Indicator timestamps and evaluation coverage SHOULD converge, but a later read MAY reflect a strictly newer evaluation; buyers reconcile toward the newerindicators_as_ofrather than treating a legitimate reevaluation between calls as incoherence. - Indicator polling is always available through
get_media_buyswhensupported_indicator_typesis declared. Sellers may additionally accept prospectiveindicators.changedand independently acceptcreative.assignment_changed, including when they are inline-only. Receivers of either event establish a complete all-status or known-ID baseline and repair throughget_media_buysrather than treating payloads or the bounded reverse projection as complete relationship state. - When
accountandinclude_pricing=trueare provided, agents that charge MUST includepricing_optionson each creative — an array ofvendor-pricing-optionobjects. Vendors may offer multiple options per creative (volume tiers, context-specific rates, different pricing models).
- 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_runfor validation without applying changes - Agents MUST reject requests that combine
delete_missing: truewithcreative_ids—delete_missingapplies to the entire library, not a filtered subset - Agents that advertise
creative.localizationMUST reject unsupported localization before mutation and return exact localization readback on every accepted localized creative - Agents that also manage media buys SHOULD support the
assignmentsfield for bulk creative-to-package mapping - Standalone creative agents that do not manage media buys SHOULD ignore the
assignmentsfield
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.fieldidentifiestarget_capability_idor 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.fieldidentifies the offending asset path)
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:- Support at least one specified transport (MCP or A2A)
- Implement
get_adcp_capabilitiesand publish canonicalcreative.supported_formats[] - Give every supported-format entry a stable
capability_idand accurate operations - Validate manifests against format specifications
- Use specified error codes
- Implement
build_creativefor creative generation - Implement
preview_creativefor preview rendering - Support universal macros in tracking URLs
- Implement
list_creativeswhen the agent hosts a creative library - Implement
sync_creativeswhen the agent accepts creative uploads - Support
creative_idinbuild_creativewhen the agent hosts a creative library - Implement the accounts protocol (
sync_accounts/list_accounts) when hosting a creative library - Declare
supports_generation,supports_transformation, andhas_creative_libraryinget_adcp_capabilitiesso buyers can determine the correct interaction model
Consumer conformance
A conformant Creative Protocol consumer MUST:- Discover creative operations through
creative.supported_formats[]and route builds withtarget_capability_id(s) - Validate manifests against format specifications before submission
- Handle validation errors appropriately
- 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-matchcreative.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:- Resolve the selected canonical product/publisher declaration
- For each manifest asset, find the corresponding declared slot
- Validate its explicit
asset_typediscriminator and constraints against that slot
asset_type; slot lookup supplies the permitted role and narrowing constraints.
Standard vs custom formats
- Canonical formats: Registered AdCP
format_kindcontracts shared across publishers, sellers, and creative agents - Custom formats:
format_kind: "custom"plus a recognizedformat_shapeand digest-pinnedformat_schema
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.