Module adcp.types.creative

AdCP creative types — curated partial surface.

Creative + format types — sync / build / preview creatives, creative status and approval, formats, and the open creative-asset union.

A stable, narrow alternative to importing the whole :mod:adcp.types namespace. Every name here is also exported from :mod:adcp.types; this module simply groups the ones a creative integration reaches for, and never exposes the internal generated layer.

This module is for curation and discoverability, not a separate performance tier: importing it is cheap, but the first access to any AdCP type (here or via :mod:adcp.types / :mod:adcp) realizes the full generated Pydantic graph — there is no per-domain graph. Use it for a smaller, focused import surface.

from adcp.types.creative import SyncCreativesRequest

Classes

class Asset (**data: Any)
Expand source code
class Asset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_id: Annotated[str, Field(description='Unique identifier')]
    asset_type: Annotated[AssetContentType, Field(description='Type of asset content')]
    url: Annotated[AnyUrl, Field(description='URL to CDN-hosted asset file')]
    tags: Annotated[
        list[str] | None,
        Field(description="Tags for discovery (e.g., 'hero', 'lifestyle', 'product', 'holiday')"),
    ] = None
    name: Annotated[
        LocalizedScalar | None,
        Field(description='Human-readable name, either a legacy plain string or localized values.'),
    ] = None
    description: Annotated[
        LocalizedScalar | None,
        Field(
            description='Asset description or usage notes, either a legacy plain string or localized values.'
        ),
    ] = None
    width: Annotated[SchemaInt | None, Field(description='Image/video width in pixels')] = None
    height: Annotated[SchemaInt | None, Field(description='Image/video height in pixels')] = None
    duration_seconds: Annotated[
        StrictFloat | None, Field(description='Video/audio duration in seconds')
    ] = None
    file_size_bytes: Annotated[SchemaInt | None, Field(description='File size in bytes')] = None
    format: Annotated[str | None, Field(description="File format (e.g., 'jpg', 'mp4', 'mp3')")] = (
        None
    )
    metadata: Annotated[
        dict[str, Any] | None, Field(description='Additional asset-specific metadata')
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_id : str
var asset_type : AssetContentType
var description : LocalizedScalar | None
var duration_seconds : float | None
var file_size_bytes : int | None
var format : str | None
var height : int | None
var metadata : dict[str, typing.Any] | None
var model_config
var name : LocalizedScalar | None
var tags : list[str] | None
var url : pydantic.networks.AnyUrl
var width : int | None

Inherited members

class AssetContentType (*args, **kwds)
Expand source code
class AssetContentType(StrEnum):
    image = 'image'
    video = 'video'
    audio = 'audio'
    text = 'text'
    markdown = 'markdown'
    html = 'html'
    css = 'css'
    javascript = 'javascript'
    zip = 'zip'
    vast = 'vast'
    daast = 'daast'
    url = 'url'
    webhook = 'webhook'
    brief = 'brief'
    catalog = 'catalog'
    published_post = 'published_post'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var audio
var brief
var catalog
var css
var daast
var html
var image
var javascript
var markdown
var published_post
var text
var url
var vast
var video
var webhook
var zip
class RepeatableAssetGroup (**data: Any)
Expand source code
class Assets29(AdCPBaseModel):
    item_type: Annotated[
        Literal['repeatable_group'],
        Field(description='Discriminator indicating this is a repeatable asset group'),
    ] = 'repeatable_group'
    asset_group_id: Annotated[
        str, Field(description="Identifier for this asset group (e.g., 'product', 'slide', 'card')")
    ]
    required: Annotated[
        StrictBool,
        Field(
            description='Whether this asset group is required. If true, at least min_count repetitions must be provided.'
        ),
    ]
    min_count: Annotated[
        SchemaInt,
        Field(
            description='Minimum number of repetitions required (if group is required) or allowed (if optional)',
            ge=0,
        ),
    ]
    max_count: Annotated[
        SchemaInt, Field(description='Maximum number of repetitions allowed', ge=1)
    ]
    selection_mode: Annotated[
        SelectionMode | None,
        Field(
            description="How the platform uses repetitions of this group. 'sequential' means all items display in order (carousels, playlists). 'optimize' means the platform selects the best-performing combination from alternatives (asset group optimization like Meta Advantage+ or Google Pmax)."
        ),
    ] = SelectionMode.sequential
    assets: Annotated[
        list[Assets30], Field(description='Assets within each repetition of this group')
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_group_id : str
var assets : list[Assets31 | Assets32 | Assets33 | Assets34 | Assets35 | Assets36 | Assets37 | Assets38 | Assets40 | Assets41 | Assets42 | Assets43 | UnknownGroupAsset]
var item_type : Literal['repeatable_group']
var max_count : int
var min_count : int
var model_config
var required : bool
var selection_mode : SelectionMode | None

Inherited members

class AudioContent (**data: Any)
Expand source code
class AudioAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['audio'],
        Field(
            description='Discriminator identifying this as an audio asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'audio'
    url: Annotated[AnyUrl, Field(description='URL to the audio asset')]
    duration_ms: Annotated[
        SchemaInt | None, Field(description='Audio duration in milliseconds', ge=0)
    ] = None
    file_size_bytes: Annotated[SchemaInt | None, Field(description='File size in bytes', ge=1)] = (
        None
    )
    container_format: Annotated[
        str | None,
        Field(description='Audio container/file format (mp3, m4a, aac, wav, ogg, flac, etc.)'),
    ] = None
    codec: Annotated[
        str | None,
        Field(
            description='Audio codec used (aac, aac_lc, he_aac, pcm, mp3, vorbis, opus, flac, ac3, eac3, etc.)'
        ),
    ] = None
    sampling_rate_hz: Annotated[
        SchemaInt | None, Field(description='Sampling rate in Hz (e.g., 44100, 48000, 96000)')
    ] = None
    channels: Annotated[
        audio_channel_layout.AudioChannelLayout | None, Field(description='Channel configuration')
    ] = None
    bit_depth: Annotated[BitDepth | None, Field(description='Bit depth')] = None
    bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Bitrate in kilobits per second', ge=1)
    ] = None
    loudness_lufs: Annotated[
        StrictFloat | None, Field(description='Integrated loudness in LUFS')
    ] = None
    true_peak_dbfs: Annotated[StrictFloat | None, Field(description='True peak level in dBFS')] = (
        None
    )
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the audio content')
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['audio']
var bit_depth : BitDepth | None
var bitrate_kbps : int | None
var channels : AudioChannelLayout | None
var codec : str | None
var container_format : str | None
var duration_ms : int | None
var file_size_bytes : int | None
var loudness_lufs : float | None
var model_config
var provenance : Provenance | None
var sampling_rate_hz : int | None
var transcript_url : pydantic.networks.AnyUrl | None
var true_peak_dbfs : float | None
var url : pydantic.networks.AnyUrl

Inherited members

class BriefAsset (**data: Any)
Expand source code
class BriefAsset(CreativeBrief):
    asset_type: Annotated[
        Literal['brief'],
        Field(
            description='Discriminator identifying this as a brief asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'brief'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['brief']
var model_config

Inherited members

class LegacyBuildCreativeRequest (**data: Any)
Expand source code
class BuildCreativeRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    governance_context: Annotated[
        str | None,
        Field(
            description='Opaque intent authorization when this creative execution incurs vendor cost.',
            max_length=4096,
            min_length=1,
            pattern='^[\\x20-\\x7E]+$',
        ),
    ] = None
    message: Annotated[
        str | None,
        Field(
            description='Natural language instructions for the transformation or generation. For pure generation, this is the creative brief. For transformation, this provides guidance on how to adapt the creative. For refinement, this describes the desired changes.'
        ),
    ] = None
    creative_manifest: Annotated[
        creative_manifest_1.CreativeManifest | None,
        Field(
            description='Creative manifest to transform or generate from. On the canonical 3.2 path it carries `format_kind`, optional `format_option_ref`, and the required input assets. For transformation (for example resizing or reformatting), this is the complete creative to adapt. When creative_id is provided, the agent resolves the creative from its library and this field is ignored.'
        ),
    ] = None
    creative_representation_set: Annotated[
        creative_representation_set_1.CreativeRepresentationSet | None,
        Field(
            description="Complete creative revision containing equivalent trafficking representations, of which exactly one is selected for this seller-bound output. This mode is accepted only by the destination sales agent and requires representation_destination plus representation_selection_strategy. The target capability selects the seller's build route; representation_destination supplies the binding inventory contract. The resolver verifies revision_content_digest against the complete set, retains every representation unchanged, selects exactly one compatible representation, and returns a manifest carrying representation_selection. If macro_values is present, selection happens first and binding affects only the derived output; the retained representation set and its revision binding never change. When none is compatible, the request fails with CREATIVE_REPRESENTATION_UNRESOLVED and one representation_rejections entry per candidate."
        ),
    ] = None
    representation_destination: Annotated[
        representation_destination_1.RepresentationDestination | None,
        Field(
            description='Seller-owned product and effective format context for representation resolution. Required only with creative_representation_set and meaningful only when this endpoint is the destination sales agent.'
        ),
    ] = None
    representation_selection_strategy: Annotated[
        representation_selection_strategy_1.RepresentationSelectionStrategy | None,
        Field(
            description='Deterministic strategy to apply after compatibility filtering. Required with creative_representation_set and MUST be advertised by creative.representation_resolution.strategies.'
        ),
    ] = None
    creative_id: Annotated[
        str | None,
        Field(
            description="Reference to a creative in the agent's library. The creative agent resolves this to a manifest from its library. Use this instead of creative_manifest when retrieving an existing creative for tag generation or format adaptation."
        ),
    ] = None
    concept_id: Annotated[
        str | None,
        Field(
            description='Creative concept containing the creative. Creative agents SHOULD assign globally unique creative_id values; when they cannot guarantee uniqueness, concept_id is REQUIRED to disambiguate.'
        ),
    ] = None
    media_buy_id: Annotated[
        str | None,
        Field(
            description='Media buy identifier for tag generation context. When the creative agent is also the ad server, this provides the trafficking context needed to generate placement-specific tags (e.g., CM360 placement ID). Not needed when tags are generated at the creative level (most creative platforms).'
        ),
    ] = None
    package_id: Annotated[
        str | None,
        Field(
            description='Package identifier within the media buy. Used with media_buy_id when the creative agent needs line-item-level context for tag generation. Omit to get a tag not scoped to a specific package.'
        ),
    ] = None
    target_format_id: Annotated[
        format_id.FormatReferenceStructuredObject | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format selector. Use `target_capability_id` with a value advertised in `get_adcp_capabilities.creative.supported_formats[].capability_id`.',
        ),
    ] = None
    target_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format selectors. Use `target_capability_ids` with values advertised in `get_adcp_capabilities.creative.supported_formats[].capability_id`.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    target_capability_id: Annotated[
        str | None,
        Field(
            description='Canonical 3.2 single-output selector. Matches exactly one `get_adcp_capabilities.creative.supported_formats[].capability_id` advertised by this creative agent. The matched entry supplies the canonical `format` declaration used to validate inputs and the returned manifest. Mutually exclusive with `target_capability_ids` and the deprecated target_format_id fields.',
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ] = None
    target_capability_ids: Annotated[
        list[TargetCapabilityId] | None,
        Field(
            description='Canonical 3.2 multi-output selector. Each value matches a `get_adcp_capabilities.creative.supported_formats[].capability_id`. The creative agent produces one canonical manifest per capability in request order. Mutually exclusive with `target_capability_id` and the deprecated target_format_id fields.',
            max_length=50,
            min_length=1,
        ),
    ] = None
    transformer_id: Annotated[
        str | None,
        Field(
            description="Selects an account-scoped transformer (discovered via list_transformers) to perform the build. One transformer per call. When present, the build uses this transformer and target_capability_id/target_capability_ids select which of its outputs to produce — they MUST be a subset of the transformer's output_capability_ids. Deprecated target_format_id fields use the legacy output_format_ids compatibility path. Render configuration goes in `config`."
        ),
    ] = None
    config: Annotated[
        dict[str, Any] | None,
        Field(
            description='Typed render configuration for the selected transformer, keyed by each param\'s `field` (from the transformer\'s params[] in list_transformers). Example: { "voice": "isaac", "speaking_rate": 1.1, "mastering_preset": "podcast" }. The agent MUST validate `config` against the transformer\'s live params for this account and reject unrecognized keys and out-of-range / non-enumerated values with a field-attributed error (e.g. `config.voice`) rather than silently ignoring them — config drives a paid render. Genuinely vendor-specific or experimental knobs not declared as params belong in `ext`, not here. (The schema leaves this object open because legal keys are dynamic per transformer; strict validation is a normative agent obligation.) When `refine_from_build_variant_id` is set, `config` is applied as a DELTA over the parent leaf\'s config.'
        ),
    ] = None
    refine_from_build_variant_id: Annotated[
        str | None,
        Field(
            description='Refine a previously produced variant and return new lineage-linked variants. The transformer and target capability are inherited from the parent leaf. A refinement request MUST omit transformer_id, target_capability_id(s), and deprecated target_format_id(s); changing transformer or output format is a new transformation build, not refinement. Requires creative.supports_refinement.'
        ),
    ] = None
    mode: Annotated[
        Mode | None,
        Field(
            description="`execute` (default) produces and bills the creative(s). `estimate` is a DRY RUN: the agent produces nothing and bills nothing, and returns a BuildCreativeEstimate with a projected cost band (cost_low/cost_high) computed against THIS request's actual inputs (script length, brief, catalog size, max_creatives × max_variants) — the band the buyer cannot derive itself, since per_unit gives the rate but not the unit count. Requires the agent to advertise `creative.supports_spend_controls`; otherwise rejected with `UNSUPPORTED_FEATURE`."
        ),
    ] = Mode.execute
    max_spend: Annotated[
        MaxSpend | None,
        Field(
            description='Hard per-call spend ceiling. The agent produces leaves until the NEXT leaf would push the run\'s aggregate vendor_cost over `amount`, then STOPS and returns the partial BuildCreativeVariantSuccess produced so far with `budget_status: "capped"` (every returned leaf is real, trafficable, and billed — nothing produced is discarded; the leaf shortfall is `leaves_returned` < `leaves_total`). If even the first leaf would exceed the cap, the call fails with BUDGET_CAP_REACHED. `currency` MUST match the rate card\'s currency (the agent does not FX-convert) or the request is rejected with INVALID_REQUEST (error.field `max_spend.currency`). Requires `creative.supports_spend_controls`. Caps a SINGLE call — to bound a refinement loop, track aggregate vendor_cost across calls and stop issuing them (buyer responsibility in this revision). max_spend bounds only build-time vendor_cost: CPM-priced builds (estimate basis `cpm_deferred`) have build-time vendor_cost 0 and accrue at serve time, so max_spend never engages for them — bound a CPM fan-out with max_creatives instead.'
        ),
    ] = None
    max_creatives: Annotated[
        SchemaInt | None,
        Field(
            description='Caps how many DISTINCT creatives to produce along the catalog/item fan-out axis — one creative per catalog item. Use it to sample a large catalog (e.g. send 150 job openings, set max_creatives: 5 to preview five). Distinct from item_limit, which caps how many catalog items a SINGLE creative consumes (DCO-style). Omitted with a catalog input means one creative per item up to the catalog/format bound; omitted without a catalog collapses to a single creative. Large fan-outs may return asynchronously. Mutually exclusive with `refine_from_build_variant_id` (refinement targets one prior creative, not a catalog fan-out). Supported only when the agent advertises `creative.multiplicity.supports_catalog_fanout`; values above `max_creatives_limit` are clamped. Pair with `max_spend` to bound the bill of a large fan-out.',
            ge=1,
        ),
    ] = None
    signal_conditions: Annotated[
        list[SignalCondition] | None,
        Field(
            description="Advisory keep-all PRODUCTION axis: produce one distinct creative group per signal condition, each kept and trafficked with its own signal targeting (e.g. a rain creative AND a sun creative). Sibling to max_creatives (catalog axis), NOT a variant_axis value (which is choose-among). Each item reuses SignalTargeting (value_type-discriminated binary/categorical/numeric over signal_ref) so the produced group's signal_condition resolves condition identity through the SAME schema the sales-side package targeting uses, plus an optional signal_agent_segment_id carrying the RESOLVED-segment identity (vs signal_ref's definition identity) — echo a provider-exposed handle verbatim; it is the primary trafficking-compatibility key, with categorical signal_ref+value as the weaker fallback. Per #5280 this is an ADVISORY context pointer — it informs production and MUST NOT hard-block at the build_creative layer; trafficking-compatibility (a sun creative MUST NOT serve into rain-targeted packages) is enforced reject-at-trafficking on the sales side (SIGNAL_TARGETING_INCOMPATIBLE), not here. Triggers the BuildCreativeVariantSuccess shape. Supported only when the agent advertises creative.multiplicity.supports_signal_fanout; condition counts above max_signal_conditions_limit are CLAMPED (not rejected), consistent with max_creatives. Composes with max_creatives (catalog × conditions cross-product) and max_variants (variants per group).",
            min_length=1,
        ),
    ] = None
    max_variants: Annotated[
        SchemaInt | None,
        Field(
            description='Caps how many ALTERNATIVES to produce per creative (different voices, themes, best-of-N, etc.). Default 1 preserves single-output behavior. Each variant is a real, independently-billed build (you pay for all produced); the buyer keeps one or many. When variant_axis.values[] is provided, its length is authoritative over max_variants. Resolutions/quality tiers are NOT variants — request them as additional target formats.',
            ge=1,
        ),
    ] = 1
    variant_axis: Annotated[
        VariantAxis | None,
        Field(
            description='Declares the dimension along which variants differ. When `values` is provided, the agent produces exactly one variant per value (e.g. an A/B of two voices). When only `dimension` is provided, the agent chooses up to max_variants variants along that dimension (e.g. best-of-N, themes).'
        ),
    ] = None
    keep_mode: Annotated[
        KeepMode | None,
        Field(
            description='Advisory hint for how the buyer intends to use the variants. `keep_one` (best-of-N) and `keep_some` signal the agent to set `recommended`/`rank` on returned variants. Advisory only — it does not change what is returned or billed; every produced variant is returned and charged. Keeping is a client act of trafficking the chosen build_variant_id(s).'
        ),
    ] = KeepMode.keep_all
    selection_strategy: Annotated[
        creative_selection_strategy.CreativeSelectionStrategy | None,
        Field(
            description='Governs HOW the agent samples when max_creatives < items_total (folds #5262). audience_relevance draws its ranking input from the SAME signal_ref pointers in signal_conditions / package targeting — NOT a parallel signals[] array. proximity takes a location input (geo shape TBD — WG open). inventory_priority is seller-side catalog metadata (margin/overstock/promo; no buyer input). random is the status-quo default. Per-creative selection ordering surfaces on the existing rank / recommended fields of creatives[].variants[], not a new selection_rank. Advisory; absent => agent default (random).'
        ),
    ] = None
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account reference for pricing and billing. When present, the creative agent applies account-specific pricing from the rate card, records the build against the account for billing, and can enforce account-level quotas or entitlements. Required by creative agents that charge for their services.'
        ),
    ] = None
    brand: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description='Brand reference for creative generation. Resolved to full brand identity (colors, logos, tone) at execution time.'
        ),
    ] = None
    quality: Annotated[
        creative_quality.CreativeQuality | None,
        Field(
            description="Quality tier for generation. 'draft' produces fast, lower-fidelity output for iteration and review. 'production' produces full-quality output for final delivery. If omitted, the creative agent uses its own default. For non-generative transforms (e.g., format resizing), creative agents MAY ignore this field."
        ),
    ] = None
    evaluator: Annotated[
        evaluator_spec.EvaluatorSpec | None,
        Field(
            description="Optional advisory evaluator (buyer-attached pointer, #5280) declaring how produced variants should be evaluated and ranked — the rank-side of the get_creative_features feature oracle. Experimental (x-status: experimental): the whole evaluator surface is new and unfrozen, and requires creative.supports_evaluator, which sellers MUST pair with `creative.evaluator` in experimental_features. Drives the producing agent's gate-then-rank pipeline over its best_of_n exploration: per leaf, evaluate (the chosen form) → optionally GATE (`evaluator.feature_requirement[]`, drop fails — internal pruning of which leaves the agent recommends, never an AdCP-layer block of an already-produced billable leaf) → RANK survivors (`evaluator.rank_by`, an explicit {feature_id, direction} ordering). Feature discovery uses get_adcp_capabilities governance.creative_features for rank_by, feature_requirement, and eval.features[]; evaluator_id is a pre-provisioned/account-arranged preset, not an ID discovered from that catalog. Populates a per-leaf `eval` block of creative-feature values (creative-feature-result[]) when supports_evaluator. When the evaluator names an external agent (`evaluator.feature_agent.agent_url` or the agent-form `agent_url`), that agent MUST appear in the seller's `creative_policy.accepted_verifiers[]` (the same allowlist #5280 established for provenance verify_agent); an off-list agent is rejected with `EVALUATOR_AGENT_NOT_ACCEPTED`. The outbound evaluator call authenticates on the transport (request signing/JWKS, mTLS, or a pre-provisioned static credential); credentials and caller-supplied trust material MUST NOT appear in evaluator, context, ext, or creative payload fields, and credential- or trust-material keys should be rejected with `CREDENTIAL_IN_ARGS`. With no `feature_requirement`, evaluation is advisory only and does not change what is produced or billed; an unreachable/unknown on-list agent degrades to seller-default ranking (advisory errors[] note), not a failure. Requires creative.supports_evaluator; otherwise ignored."
        ),
    ] = None
    item_limit: Annotated[
        SchemaInt | None,
        Field(
            description="Maximum number of catalog items a SINGLE creative consumes when generating (DCO-style — e.g. how many items fill one carousel/feed creative). When a catalog asset contains more items than this limit, the creative agent selects the top items based on relevance or catalog ordering. When item_limit exceeds the format's max_items, the creative agent SHOULD use the lesser of the two. Ignored when the manifest contains no catalog assets. Distinct from `max_creatives`, which fans OUT across catalog items to produce one distinct creative per item.",
            ge=1,
        ),
    ] = None
    include_preview: Annotated[
        StrictBool | None,
        Field(
            description="When true, requests the creative agent to include preview renders in the response alongside the manifest. Agents that support this return a 'preview' object in the response using the same structure as preview_creative. Agents that do not support inline preview simply omit the field. This avoids a separate preview_creative round trip for platforms that generate previews as a byproduct of building."
        ),
    ] = None
    preview_inputs: Annotated[
        list[PreviewInput] | None,
        Field(
            description='Input sets for preview generation when include_preview is true. Supported with a single target_capability_id; multi-capability requests generate one default preview per output. Deprecated target-format selectors retain equivalent compatibility behavior.',
            min_length=1,
        ),
    ] = None
    preview_quality: Annotated[
        creative_quality.CreativeQuality | None,
        Field(
            description="Render quality for inline preview when include_preview is true. 'draft' produces fast, lower-fidelity renderings. 'production' produces full-quality renderings. Independent of the build quality parameter — you can build at draft quality and preview at production quality, or vice versa. If omitted, the creative agent uses its own default. Ignored when include_preview is false or omitted."
        ),
    ] = None
    preview_output_format: Annotated[
        preview_output_format_1.PreviewOutputFormat | None,
        Field(
            description="Output format for preview renders when include_preview is true. 'url' returns preview_url (iframe-embeddable URL), 'html' returns preview_html (raw HTML). Ignored when include_preview is false or omitted."
        ),
    ] = preview_output_format_1.PreviewOutputFormat.url
    macro_values: Annotated[
        dict[str, str] | None,
        Field(
            description="Raw concrete values offered for build-time binding, keyed by AdCP universal semantic (for example CLICK_URL or CACHEBUSTER). With declarations, a value binds only a verified-universal `resolve_value` occurrence performed_by `creative_agent`, using that declaration's exact context and encoding; callers MUST NOT pre-encode it. The selected `creative.supported_formats[]` route's macro_resolution_capabilities is the binding build/preview capability set; seller-wide and product sets apply only on the sales execution path. Values never short-circuit `translate_to_native`: translation emits its target declaration and the complete target capability chain remains required. For creative_representation_set, selection happens before binding and the complete representation set remains byte-identical. Without declarations, the 3.x legacy path remains: creative agents may translate recognized AdCP tokens using the existing `translateUniversalMacros` contract, preserve omitted placeholders for the sales agent, and ignore unknown keys. Existing unmapped/frozen-consent diagnostics remain required."
        ),
    ] = None
    idempotency_key: Annotated[
        str,
        Field(
            description='Client-generated unique key for this request. Prevents duplicate creative generation on retries. MUST be unique per (seller, request) pair to prevent cross-seller correlation. Use a fresh UUID v4 for each request.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ]
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Optional webhook configuration for async terminal completion/failure notifications on build_creative. Meaningful only when the request enters the async lifecycle and returns a Submitted envelope. Submitted envelopes with `task_id` remain pollable through `get_task_status` (legacy `tasks/get`) whether or not this field is present. If a request includes this field and the agent returns a Submitted envelope, the agent MUST deliver at least the terminal completion/failure notification to the configured URL; intermediate progress notifications are MAY. If the agent cannot honor the webhook channel, it MUST reject the request with a structured error instead of silently accepting. This field does not change response timing semantics: agents MUST NOT route a request through the async/Submitted arm or emit async delivery solely because `push_notification_config` is present; requests that can be completed inline still return the synchronous success shape.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The request message of a task in the pinned bundle's task registry.

A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is. issubclass(model, AdcpRequest) is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.

Each accessor returns the field's value, or None when this tool's schema declares no such field. Only 49 of the 87 request schemas declare an account and only 43 an idempotency_key, so asking the request is what replaces getattr(req, "account", None) against Any at the boundary.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var brand : BrandReference | None
var concept_id : str | None
var config : dict[str, typing.Any] | None
var context : ContextObject | None
var creative_id : str | None
var creative_manifest : CreativeManifest | None
var creative_representation_set : CreativeRepresentationSet | None
var evaluator : EvaluatorSpec1 | EvaluatorSpec2 | EvaluatorSpec3 | None
var ext : ExtensionObject | None
var governance_context : str | None
var idempotency_key : str
var include_preview : bool | None
var item_limit : int | None
var keep_mode : KeepMode | None
var macro_values : dict[str, str] | None
var max_creatives : int | None
var max_spend : MaxSpend | None
var max_variants : int | None
var media_buy_id : str | None
var message : str | None
var mode : Mode | None
var model_config
var package_id : str | None
var preview_inputs : list[PreviewInput] | None
var preview_output_format : PreviewOutputFormat | None
var preview_quality : CreativeQuality | None
var push_notification_config : PushNotificationConfig | None
var quality : CreativeQuality | None
var refine_from_build_variant_id : str | None
var representation_destination : RepresentationDestination | None
var representation_selection_strategy : RepresentationSelectionStrategy | None
var selection_strategy : CreativeSelectionStrategy | None
var signal_conditions : list[SignalCondition5 | SignalCondition6 | SignalCondition7] | None
var target_capability_id : str | None
var target_capability_ids : list[TargetCapabilityId] | None
var target_format_id : FormatReferenceStructuredObject | None
var target_format_ids : list[FormatReferenceStructuredObject] | None
var transformer_id : str | None
var variant_axis : VariantAxis | None

Inherited members

class LegacyBuildCreativeSuccessResponse (**data: Any)
Expand source code
class BuildCreativeResponse1(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    creative_manifest: creative_manifest_1.CreativeManifest
    build_variant_id: str | None = None
    recipe_hash: str | None = None
    sandbox: bool | None = None
    expires_at: AwareDatetime | None = None
    preview: Preview | None = None
    preview_error: error_1.Error | None = None
    pricing_option_id: str | None = None
    vendor_cost: Annotated[float, Field(ge=0)] | None = None
    currency: Annotated[str, StringConstraints(pattern='^[A-Z]{3}$')] | None = None
    consumption: creative_consumption_1.CreativeConsumption | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var build_variant_id : str | None
var consumption : CreativeConsumption | None
var context : ContextObject | None
var creative_manifest : adcp.types._forward_compat._ReadbackCreativeManifest
var currency : str | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var model_config
var preview : Preview | None
var preview_error : Error | None
var pricing_option_id : str | None
var recipe_hash : str | None
var sandbox : bool | None
var vendor_cost : float | None

Instance variables

var adcp_major_version : int | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class LegacyBuildCreativeErrorResponse (**data: Any)
Expand source code
class BuildCreativeResponse2(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    errors: Annotated[list[error_1.Error], Field(min_length=1)]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var errors : list[Error]
var ext : ExtensionObject | None
var model_config

Inherited members

class LegacyBuildCreativeSubmittedResponse (**data: Any)
Expand source code
class BuildCreativeResponse6(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow', validate_default=True)
    status: Literal[task_status_1.TaskStatus.submitted] = task_status_1.TaskStatus.submitted
    task_id: str
    message: Annotated[str, StringConstraints(max_length=2000)] | None = None
    errors: list[error_1.Error] | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal[]
var task_id : str

Inherited members

class CardAsset (**data: Any)
Expand source code
class CardAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['card'],
        Field(
            description='Discriminator identifying this as a card asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'card'
    media: Annotated[
        asset_union.ImageAsset | asset_union.VideoAsset,
        Field(
            description="The card's primary visual asset. Either an `image` or `video` asset, matching the parent format's `allowed_card_media_asset_types` parameter.",
            discriminator='asset_type',
        ),
    ]
    headline: Annotated[
        str | None,
        Field(
            description='Optional per-card short text label (typically 25-40 chars). Length governed by `card_headline_max_chars` on the format declaration. Meta carousel headline, Pinterest pin title, Snap Collection sticker text, TikTok caption-short.'
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(
            description='Optional per-card longer text (typically 100-500 chars). Distinct from `headline`: `description` is body copy, `headline` is the label. Length governed by `card_description_max_chars` on the format declaration. Meta carousel description, Pinterest pin description, AI-surface result body text, TikTok long caption.'
        ),
    ] = None
    cta: Annotated[
        str | None,
        Field(
            description="Optional per-card call-to-action label (e.g., 'SHOP_NOW', 'LEARN_MORE'). When the parent format declares `cta_values` (allowed CTA labels), the per-card `cta` MUST be one of those values. Lets a Meta or TikTok carousel show different CTAs per card."
        ),
    ] = None
    landing_page_url: Annotated[
        asset_union.UrlAsset | None,
        Field(
            description='Optional per-card click-through URL. URL asset with `url_type: "clickthrough"`.'
        ),
    ] = None
    platform_extensions: Annotated[
        list[asset_union.PlatformExtensionRef] | None,
        Field(
            description='Per-card platform-specific extensions (URI+digest references). Same hosting model as format-level platform_extensions. Use this for Meta carousel-card attributes, Pinterest pin overrides, etc. — NEVER inline non-canonical keys on the card object directly.'
        ),
    ] = None
    provenance: Annotated[
        asset_union.Provenance | None,
        Field(
            description='Provenance metadata for this card, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['card']
var cta : str | None
var description : str | None
var headline : str | None
var landing_page_url : UrlAsset | None
var media : ImageAsset | VideoAsset
var model_config
var platform_extensions : list[PlatformExtensionRef] | None
var provenance : Provenance | None

Inherited members

class CatalogAsset (**data: Any)
Expand source code
class CatalogAsset(Catalog):
    asset_type: Annotated[
        Literal['catalog'],
        Field(
            description='Discriminator identifying this as a catalog asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'catalog'

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['catalog']
var model_config

Inherited members

class Creative (**data: Any)
Expand source code
class Creative(_CanonicalListedCreative, CanonicalBoundaryModel):
    """Canonical listed creative; the format kind is required, not optional.

    A listed creative is a row a seller RETURNS, so the kind is required but
    never confined: a kind a newer seller emits is retained as-is, which is
    what ``core/canonical-format-kind.json`` requires of a consumer.
    """

    if TYPE_CHECKING:  # the removed field, hidden from the constructor too
        format_id: _RemovedFormatId = Field(default=None, init=False)

    format_kind: str

Canonical listed creative; the format kind is required, not optional.

A listed creative is a row a seller RETURNS, so the kind is required but never confined: a kind a newer seller emits is retained as-is, which is what core/canonical-format-kind.json requires of a consumer.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject | None
var format_kind : str
var model_config

Inherited members

class CreativeAgent (**data: Any)
Expand source code
class CreativeAgent(AdCPBaseModel):
    agent_url: Annotated[
        AnyUrl,
        Field(
            description="Base URL for the creative agent (e.g., 'https://reference.example.com', 'https://dco.example.com')."
        ),
    ]
    agent_name: Annotated[
        str | None, Field(description='Human-readable name for the creative agent')
    ] = None
    capabilities: Annotated[
        list[creative_agent_capability.CreativeAgentCapability] | None,
        Field(description='Capabilities this creative agent provides'),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_name : str | None
var agent_url : pydantic.networks.AnyUrl
var capabilities : list[CreativeAgentCapability] | None
var model_config

Inherited members

class CreativeApproval (**data: Any)
Expand source code
class CreativeApproval(IndicatorBearingResourceState):
    model_config = ConfigDict(
        extra='allow',
    )
    indicator_types_evaluated: Annotated[
        list[IndicatorTypesEvaluatedEnum2] | None,
        Field(
            description='Indicator types covered by this snapshot. Required whenever indicators is present. Types omitted from this list remain unknown even when indicators is empty. Every returned indicator.type MUST appear in this list.',
            min_length=1,
        ),
    ] = None
    indicators: Annotated[
        list[Indicator2] | None,
        Field(
            description='Current seller assertions for the indicator types and publisher/placement coverage named by the sibling evaluation fields. Omitted means unknown or not evaluated. A present empty array means evaluated with no current assertion for indicator_types_evaluated in the evaluated scope.'
        ),
    ] = None
    creative_id: Annotated[str, Field(description='Creative identifier')]
    approval_status: creative_approval_status.CreativeApprovalStatus
    rejection_reason: Annotated[
        str | None,
        Field(
            description="Human-readable explanation of why the creative was rejected. Present only when approval_status is 'rejected'."
        ),
    ] = None
    approval_scopes: Annotated[
        list[creative_approval_scope.ScopedCreativeApproval] | None,
        Field(
            description='Complete, disjoint publisher/placement approval partition when approval_status is partially_approved. A normalized scope appears once. For one publisher, use either one publisher-wide row or placement-specific rows, never both. Omit when one approval_status applies uniformly to the whole assignment. The same scoped outcomes are mirrored on list_creatives.',
            min_length=2,
        ),
    ] = None
    indicators_as_of: Annotated[
        AwareDatetime | None,
        Field(
            description='When the seller last completed the evaluation represented by indicators for this relationship. Required whenever indicators is present, including an empty array.'
        ),
    ] = None
    indicators_evaluated_scope: Annotated[
        list[indicator_scope.IndicatorScope] | None,
        Field(
            description='Optional publisher or placement scopes covered by this evaluation. Omit when indicators covers the whole package–creative assignment. When present, scopes not listed remain unknown; every returned indicator.scope entry MUST be contained by this set.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var approval_scopes : list[ScopedCreativeApproval] | None
var approval_status : CreativeApprovalStatus
var creative_id : str
var indicator_types_evaluated : list[IndicatorTypesEvaluatedEnum2] | None
var indicators : list[Indicator2] | None
var indicators_as_of : pydantic.types.AwareDatetime | None
var indicators_evaluated_scope : list[IndicatorScope] | None
var model_config
var rejection_reason : str | None

Inherited members

class CreativeApprovalStatus (*args, **kwds)
Expand source code
class CreativeApprovalStatus(StrEnum):
    pending_review = 'pending_review'
    approved = 'approved'
    partially_approved = 'partially_approved'
    rejected = 'rejected'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var approved
var partially_approved
var pending_review
var rejected
class CreativeAsset (**data: Any)
Expand source code
class CreativeAsset(_CanonicalCreativeWire, CanonicalBoundaryModel):
    """Canonical creative asset; the format kind is required, not optional.

    The kind is narrowed to required and nothing else: it stays ``str`` and the
    model refuses no value. A buyer SENDS a creative asset, and the
    producer-side "sellers MUST NOT mint ad-hoc kinds" rule is the sender's
    obligation, not something a pinned library can tell from a kind defined
    after its pin — :func:`is_canonical_format_kind` is how a caller meets it.
    """

    if TYPE_CHECKING:  # the removed field, hidden from the constructor too
        format_id: _RemovedFormatId = Field(default=None, init=False)

    format_kind: str

Canonical creative asset; the format kind is required, not optional.

The kind is narrowed to required and nothing else: it stays str and the model refuses no value. A buyer SENDS a creative asset, and the producer-side "sellers MUST NOT mint ad-hoc kinds" rule is the sender's obligation, not something a pinned library can tell from a kind defined after its pin — :func:is_canonical_format_kind is how a caller meets it.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject | None
var format_kind : str
var model_config

Instance variables

var placement_ids : list[str] | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class CreativeAssignment (**data: Any)
Expand source code
class CreativeAssignment(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    creative_id: Annotated[str, Field(description='Unique identifier for the creative')]
    weight: Annotated[
        StrictFloat | None,
        Field(
            description="Relative delivery weight for this creative (0–100). Valid when the package's effective rotation_mode is weighted, including the backward-compatible default when rotation_mode is omitted. Weights determine impression distribution proportionally — a creative with weight 2 gets twice the delivery of weight 1. When omitted, the creative receives equal weight with other unweighted creatives. A weight of 0 means the creative is assigned but paused (receives no delivery).",
            ge=0.0,
            le=100.0,
        ),
    ] = None
    rotation_mode: Annotated[
        RotationMode | None,
        Field(
            description='Package-scoped rotation policy repeated on assignment rows for wire compatibility. Omission means weighted, preserving existing weight behavior. Every assignment in a package MUST resolve to the same effective mode: weighted uses relative weights; even balances delivery across eligible assignments; sequential cycles through sequence_position in ascending order within each group; random makes an independent uniform selection from eligible assignments. Sellers MUST reject conflicting effective modes rather than choose one by array order.'
        ),
    ] = None
    group_id: Annotated[
        str | None,
        Field(
            description="Package-local creative pool identifier. The identifier has no meaning outside this package. Assignments that omit group_id belong to the package's default group; one eligible creative is selected from each applicable group per serving opportunity.",
            min_length=1,
        ),
    ] = None
    sequence_position: Annotated[
        SchemaInt | None,
        Field(
            description="One-based order within the assignment's package-local group. Required only for sequential rotation and unique within that group.",
            ge=1,
        ),
    ] = None
    placement_refs: Annotated[
        list[placement_ref.PlacementReference] | None,
        Field(
            description="Optional structured product-context refs routing this creative within already-purchased package inventory. These items always use placement-ref product-context semantics, even when tolerated additional members make an item resemble placement-identity. Receivers match only against the package's committed placement set; kind and seller_agent are non-authoritative for routing and MUST NOT expand or reinterpret that set. A receiver MUST reject a ref when the enclosing product and committed set do not yield one unambiguous match. This field never narrows purchased inventory; use targeting_overlay.placement_selection for that. Every ref MUST fall within the package's committed placement selection. New senders SHOULD include publisher_domain for publisher-catalog placements. When omitted, the creative runs across the purchased placements compatible with its format. If both placement_refs and legacy placement_ids are present, placement_refs wins.",
            min_length=1,
        ),
    ] = None
    placement_ids: Annotated[
        list[str] | None,
        Field(
            deprecated=True,
            description='Legacy shorthand routing IDs within already-purchased inventory. This field never narrows purchased inventory; use targeting_overlay.placement_selection. New senders SHOULD use placement_refs because IDs are publisher-scoped. If placement_refs is also present, receivers MUST ignore this field.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var creative_id : str
var group_id : str | None
var model_config
var placement_ids : list[str] | None
var placement_refs : list[PlacementReference] | None
var rotation_mode : RotationMode | None
var sequence_position : int | None
var weight : float | None

Inherited members

class CreativeFilters (**data: Any)
Expand source code
class CreativeFilters(_LegacyCreativeFilters, CanonicalBoundaryModel):
    """Canonical creative filters; legacy identity selection is unavailable."""

    if TYPE_CHECKING:  # the removed field, hidden from the constructor too
        format_ids: _RemovedFormatIds = Field(default=None, init=False)

Canonical creative filters; legacy identity selection is unavailable.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_ids : list[FormatReferenceStructuredObject] | None
var model_config

Inherited members

class CreativeManifest (**data: Any)
Expand source code
class CreativeManifest(_CanonicalCreativeManifestWire, CanonicalBoundaryModel):
    """Canonical manifest accepting the SDK's public standalone asset models.

    The 3.2 aggregate asset-union schema currently generates structurally
    duplicate Pydantic classes. Convert public ``ImageContent``/``UrlContent``
    (and peers) back to their wire dictionaries before the aggregate union
    validates them. This keeps the public constructors composable without
    relaxing the on-wire discriminator checks.
    """

    if TYPE_CHECKING:  # the removed field, hidden from the constructor too
        format_id: _RemovedFormatId = Field(default=None, init=False)

    @model_validator(mode="before")
    @classmethod
    def _normalize_standalone_assets(cls, data: Any) -> Any:
        if not isinstance(data, dict) or not isinstance(data.get("assets"), dict):
            return data

        def wire_value(value: Any) -> Any:
            if isinstance(value, AdCPBaseModel):
                return value.model_dump(mode="json", exclude_none=True)
            if isinstance(value, list):
                return [wire_value(item) for item in value]
            return value

        return {
            **data,
            "assets": {key: wire_value(value) for key, value in data["assets"].items()},
        }

Canonical manifest accepting the SDK's public standalone asset models.

The 3.2 aggregate asset-union schema currently generates structurally duplicate Pydantic classes. Convert public ImageAsset/UrlAsset (and peers) back to their wire dictionaries before the aggregate union validates them. This keeps the public constructors composable without relaxing the on-wire discriminator checks.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class CreativePolicy (**data: Any)
Expand source code
class CreativePolicy(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    co_branding: Annotated[
        co_branding_requirement.CoBrandingRequirement, Field(description='Co-branding requirement')
    ]
    landing_page: Annotated[
        landing_page_requirement.LandingPageRequirement,
        Field(description='Landing page requirements'),
    ]
    templates_available: Annotated[
        StrictBool, Field(description='Whether creative templates are provided')
    ]
    provenance_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether creatives must include provenance metadata. When true, the seller requires buyers to attach provenance declarations to creative submissions. The seller may independently verify claims via get_creative_features.'
        ),
    ] = None
    provenance_requirements: Annotated[
        ProvenanceRequirements | None,
        Field(
            description='Structured provenance requirements for creatives. Refines `provenance_required`: when `provenance_required` is true, the fields in this object specify which provenance features the seller requires. When `provenance_required` is false or absent, this object SHOULD be absent; if present, receivers MUST ignore it. Existing seller agents that do not read this object are unaffected; the wire shape does not change for them. Sellers that publish a requirement here MUST enforce it on creative submission: a `sync_creatives` request that omits a required field is rejected with the corresponding `PROVENANCE_*` error code (see error-code.json), and a creative whose provenance claim is contradicted by an independent verification (`get_creative_features` against a governance agent the seller operates or has allowlisted via `accepted_verifiers`) is rejected with `PROVENANCE_CLAIM_CONTRADICTED`. This is the structural-rejection surface; the truth-of-claim surface lives in `get_creative_features`. Field-level requirements are seller-enforced — JSON Schema validation does not check them.'
        ),
    ] = None
    accepted_verifiers: Annotated[
        list[AcceptedVerifier] | None,
        Field(
            description='Governance agents the seller operates, has allowlisted, or otherwise trusts to verify provenance claims via `get_creative_features`. Buyers attaching a `verify_agent` pointer on `embedded_provenance[]` or `watermarks[]` MUST select an `agent_url` that appears in this list (canonicalized per /docs/reference/url-canonicalization: lowercase scheme and host, strip default port, normalize path dot-segments) - the buyer is *representing* that they used a verifier the seller will recognize, not asserting unilateral routing. Sellers MUST reject `sync_creatives` submissions whose `verify_agent.agent_url` does not match any entry here with `PROVENANCE_VERIFIER_NOT_ACCEPTED`. The seller is the verifier-of-record: it is the seller, not the buyer, that decides which agent it will call. Publishing the list lets buyers pre-flight their creative shape against `get_products` and lets multiple buyers converge on the same verifier without coordinating with each other.',
            min_length=1,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accepted_verifiers : list[AcceptedVerifier] | None
var co_branding : CoBrandingRequirement
var landing_page : LandingPageRequirement
var model_config
var provenance_required : bool | None
var provenance_requirements : ProvenanceRequirements | None
var templates_available : bool

Inherited members

class CreativeStatus (*args, **kwds)
Expand source code
class CreativeStatus(StrEnum):
    processing = 'processing'
    pending_review = 'pending_review'
    approved = 'approved'
    suspended = 'suspended'
    rejected = 'rejected'
    archived = 'archived'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var approved
var archived
var pending_review
var processing
var rejected
var suspended
class CreativeVariant (**data: Any)
Expand source code
class CreativeVariant(_LegacyCreativeVariant, CanonicalBoundaryModel):
    """Canonical creative variant whose manifest is the canonical manifest."""

    manifest: CreativeManifest | None = None

Canonical creative variant whose manifest is the canonical manifest.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var manifest : CreativeManifest | None
var model_config

Inherited members

class CssContent (**data: Any)
Expand source code
class CssAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['css'],
        Field(
            description='Discriminator identifying this as a CSS asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'css'
    content: Annotated[str, Field(description='CSS content')]
    media: Annotated[
        str | None, Field(description="CSS media query context (e.g., 'screen', 'print')")
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['css']
var content : str
var media : str | None
var model_config
var provenance : Provenance | None

Inherited members

class DaastAsset (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class DaastAsset(RootModel[DaastAsset3 | DaastAsset4]):
    root: Annotated[
        DaastAsset3 | DaastAsset4,
        Field(
            description='DAAST (Digital Audio Ad Serving Template) tag for third-party audio ad serving',
            discriminator='delivery_type',
            title='DAAST Asset',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[DaastAsset3, DaastAsset4]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : DaastAsset3 | DaastAsset4
class DaastTrackerAsset (**data: Any)
Expand source code
class DaastTrackerAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['daast_tracker'],
        Field(
            description='Discriminator identifying this as a DAAST tracker asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'daast_tracker'
    daast_event: Annotated[
        daast_tracking_event.DaastTrackingEvent,
        Field(
            description='The DAAST tracking event this URL fires on. MUST NOT be `impression` (model as `url` asset with `url_type: "tracker_pixel"`), `clickTracking` / `customClick` (click-tracking trackers go on their own URL asset), `error`, or any of the `ViewableImpression`-element children (`viewable`, `notViewable`, `viewUndetermined`, `measurableImpression`, `viewableImpression`).'
        ),
    ]
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Tracker URL fired for the DAAST event. Attached declarations identify each macro occurrence, processing actor, and exact encoding profile.'
        ),
    ]
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='Exact tokens in `url` and their resolver/encoding contracts.', min_length=1
        ),
    ] = None
    offset: Annotated[
        str | None,
        Field(
            description='DAAST `offset` attribute. Required when `daast_event` is `progress` (DAAST 1.1 §3.2.4.3); ignored otherwise for compatibility with existing 3.x manifests. Same format as VAST 4.2 `Tracking@offset`: `HH:MM:SS` or `HH:MM:SS.mmm` for absolute time (two-digit hours, minutes 00–59, seconds 00–59), or an integer percentage 0–100 suffixed with `%`. Negative offsets are NOT permitted.',
            pattern='^(\\d{2}:[0-5]\\d:[0-5]\\d(\\.\\d{3})?|(100|\\d{1,2})%)$',
        ),
    ] = None
    target: Annotated[
        Target | None,
        Field(
            description='Which DAAST creative element this tracker scopes to — `linear` for `<Linear>/<TrackingEvents>` (DAAST 1.1 §3.2.1.7), `companion` for `<CompanionAds>/<Companion>/<TrackingEvents>` (DAAST 1.1 §3.2.2.7). DAAST has no `<NonLinearAds>` element. Defaults to `linear`. Existing 3.x assets remain structurally permissive; a tracker execution contract applies the standards-valid event/target matrix when matching a creative to a product.'
        ),
    ] = Target.linear
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['daast_tracker']
var daast_event : DaastTrackingEvent
var macro_declarations : list[MacroDeclaration] | None
var model_config
var offset : str | None
var provenance : Provenance | None
var target : Target | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4

Inherited members

class Dimensions (**data: Any)
Expand source code
class Dimensions(AdCPBaseModel):
    width: Annotated[
        StrictFloat | None,
        Field(description='Fixed width. Interpretation depends on unit (default: pixels).', gt=0.0),
    ] = None
    height: Annotated[
        StrictFloat | None,
        Field(
            description='Fixed height. Interpretation depends on unit (default: pixels).', gt=0.0
        ),
    ] = None
    min_width: Annotated[
        StrictFloat | None, Field(description='Minimum width for responsive renders', gt=0.0)
    ] = None
    min_height: Annotated[
        StrictFloat | None, Field(description='Minimum height for responsive renders', gt=0.0)
    ] = None
    max_width: Annotated[
        StrictFloat | None, Field(description='Maximum width for responsive renders', gt=0.0)
    ] = None
    max_height: Annotated[
        StrictFloat | None, Field(description='Maximum height for responsive renders', gt=0.0)
    ] = None
    unit: Annotated[
        dimension_unit.DimensionUnit | None,
        Field(
            description="Unit of measurement for width/height values. Defaults to 'px' when absent. Print formats use 'inches' or 'cm'."
        ),
    ] = None
    responsive: Annotated[
        Responsive | None, Field(description='Indicates which dimensions are responsive/fluid')
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description="Fixed aspect ratio constraint (e.g., '16:9', '4:3', '1:1', '1.91:1')",
            pattern='^\\d+(\\.\\d+)?:\\d+(\\.\\d+)?$',
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var aspect_ratio : str | None
var height : float | None
var max_height : float | None
var max_width : float | None
var min_height : float | None
var min_width : float | None
var model_config
var responsive : Responsive | None
var unit : DimensionUnit | None
var width : float | None

Inherited members

class Format (**data: Any)
Expand source code
class Format(CanonicalBoundaryModel):
    """Canonical format declaration exposed as ``adcp.Format``."""

    format_option_id: str | None = Field(
        default=None,
        description="Stable option identifier within the product or publisher namespace.",
    )
    publisher_domain: str | None = Field(
        default=None,
        pattern=r"^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$",
    )
    display_name: str | None = None
    applies_to_channels: list[MediaChannel] | None = None
    seller_preference: SellerPreference | None = None
    canonical_formats_only: bool | None = None
    experimental: bool | None = None
    format_shape: str | None = None
    format_schema: PlatformExtensionReference | None = None
    format_kind: str
    params: dict[str, Any]

    _legacy_format_refs: list[LegacyFormatId] = PrivateAttr(default_factory=list)

    @model_validator(mode="before")
    @classmethod
    def _reject_legacy_conflicts_and_credentials(cls, data: Any) -> Any:
        if not isinstance(data, dict):
            return data
        if data.get("canonical_formats_only") is True and data.get("v1_format_ref"):
            raise ValueError(
                "canonical_formats_only=True is mutually exclusive with legacy v1_format_ref"
            )
        for bag_name, bag in (
            ("params", data.get("params")),
            (
                "extras",
                {
                    key: value
                    for key, value in data.items()
                    if key not in cls.model_fields and key != "v1_format_ref"
                },
            ),
        ):
            found = _walk_for_credential_keys(bag, path=bag_name)
            if found is not None:
                raise ValueError(
                    f"{found!r} matches a credential-shaped key suffix and cannot "
                    "be stored in a canonical format declaration"
                )
        return data

    def __init__(self, **data: Any) -> None:
        refs = data.get("v1_format_ref")
        if "capability_id" in data and "format_option_id" not in data:
            data["format_option_id"] = data.pop("capability_id")
        super().__init__(**data)
        if self.__pydantic_extra__ is not None:
            self.__pydantic_extra__.pop("v1_format_ref", None)
        if refs:
            self._legacy_format_refs = [
                LegacyFormatId.model_validate(copy.deepcopy(ref)) for ref in refs
            ]

    @property
    def legacy_format_refs(self) -> tuple[LegacyFormatId, ...]:
        """Original tuples retained only for an explicit compatibility adapter."""

        return tuple(copy.deepcopy(ref) for ref in self._legacy_format_refs)

    def params_as(self, canonical_type: type[_CanonicalParamsT]) -> _CanonicalParamsT:
        """Validate the open parameter bag against a typed canonical model."""

        return canonical_type.model_validate(self.params)

    @model_validator(mode="after")
    def _validate_custom_shape(self) -> Format:
        if self.format_kind == CanonicalFormatKind.custom.value:
            if not self.format_shape:
                raise ValueError("custom formats require format_shape")
            if self.format_schema is None:
                raise ValueError("custom formats require format_schema")
        elif self.format_shape is not None or self.format_schema is not None:
            raise ValueError("format_shape and format_schema are only valid for custom formats")
        return self

Canonical format declaration exposed as Format.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var applies_to_channels : list[MediaChannel] | None
var canonical_formats_only : bool | None
var display_name : str | None
var experimental : bool | None
var format_kind : str
var format_option_id : str | None
var format_schema : PlatformExtensionReference | None
var format_shape : str | None
var model_config
var params : dict[str, typing.Any]
var publisher_domain : str | None
var seller_preference : SellerPreference | None

Instance variables

prop legacy_format_refs : tuple[FormatReferenceStructuredObject, ...]
Expand source code
@property
def legacy_format_refs(self) -> tuple[LegacyFormatId, ...]:
    """Original tuples retained only for an explicit compatibility adapter."""

    return tuple(copy.deepcopy(ref) for ref in self._legacy_format_refs)

Original tuples retained only for an explicit compatibility adapter.

Methods

def model_post_init(self: BaseModel, context: Any, /) ‑> None
Expand source code
def init_private_attributes(self: BaseModel, context: Any, /) -> None:
    """This function is meant to behave like a BaseModel method to initialize private attributes.

    It takes context as an argument since that's what pydantic-core passes when calling it.

    Args:
        self: The BaseModel instance.
        context: The context.
    """
    if getattr(self, '__pydantic_private__', None) is None:
        pydantic_private = {}
        for name, private_attr in self.__private_attributes__.items():
            # Avoid needlessly creating a new dict for the validated data:
            if private_attr.default_factory_takes_validated_data:
                default = private_attr.get_default(
                    call_default_factory=True, validated_data={**self.__dict__, **pydantic_private}
                )
            else:
                default = private_attr.get_default(call_default_factory=True)
            if default is not PydanticUndefined:
                pydantic_private[name] = default
        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args
-----=
self
The BaseModel instance.
context
The context.
def params_as(self, canonical_type: type[_CanonicalParamsT]) ‑> ~_CanonicalParamsT
Expand source code
def params_as(self, canonical_type: type[_CanonicalParamsT]) -> _CanonicalParamsT:
    """Validate the open parameter bag against a typed canonical model."""

    return canonical_type.model_validate(self.params)

Validate the open parameter bag against a typed canonical model.

Inherited members

class FormatCard (**data: Any)
Expand source code
class FormatCard(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject,
        Field(
            description='Creative format defining the card layout (typically format_card_standard)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(description='Asset manifest for rendering the card, structure defined by the format'),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject
var manifest : dict[str, typing.Any]
var model_config

Inherited members

class FormatCardDetailed (**data: Any)
Expand source code
class FormatCardDetailed(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject,
        Field(
            description='Creative format defining the detailed card layout (typically format_card_detailed)'
        ),
    ]
    manifest: Annotated[
        dict[str, Any],
        Field(
            description='Asset manifest for rendering the detailed card, structure defined by the format'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var format_id : FormatReferenceStructuredObject
var manifest : dict[str, typing.Any]
var model_config

Inherited members

class LegacyFormatId (**data: Any)
Expand source code
class FormatReferenceStructuredObject(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    agent_url: Annotated[
        WireUrl,
        Field(
            description="URL of the agent that defines this format (e.g., 'https://creative.adcontextprotocol.org' for standard formats, or 'https://publisher.com/.well-known/adcp/sales' for custom formats). Callers comparing two `format-id` values MUST canonicalize `agent_url` per the AdCP URL canonicalization rules before treating two formats as the same. See docs/reference/url-canonicalization."
        ),
    ]
    id: Annotated[
        str,
        Field(
            description="Format identifier within the agent's namespace (e.g., 'display_static', 'video_hosted', 'audio_standard'). When used alone, references a template format. When combined with dimension/duration fields, creates a parameterized format ID for a specific variant.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Width in pixels for visual formats. When specified, height must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Height in pixels for visual formats. When specified, width must also be specified. Both fields together create a parameterized format ID for dimension-specific variants.',
            ge=1,
        ),
    ] = None
    duration_ms: Annotated[
        StrictFloat | None,
        Field(
            description='Duration in milliseconds for time-based formats (video, audio). When specified, creates a parameterized format ID. Omit to reference a template format without parameters.',
            ge=1.0,
        ),
    ] = None
    pixel_ratio: Annotated[
        StrictFloat | None,
        Field(
            description='Required intrinsic-pixel density for a parameterized visual format, expressed as intrinsic pixels per logical pixel. Requires `width` and `height`. Example: `{id: "display_image", width: 300, height: 250, pixel_ratio: 2}` identifies a 300×250 logical render supplied by a 600×500 image. Omit for the backward-compatible 1x variant.',
            gt=0.0,
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : str
var duration_ms : float | None
var height : int | None
var id : str
var model_config
var pixel_ratio : float | None
var width : int | None

Inherited members

class GetCreativeFeaturesRequest (**data: Any)
Expand source code
class GetCreativeFeaturesRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    idempotency_key: Annotated[
        str | None,
        Field(
            description='Optional in AdCP 3.x for wire compatibility; clients SHOULD send a unique key for every logical evaluation. When supplied to a provider that advertises adcp.idempotency.supported: true, exact retries with the same canonical payload MUST return the cached initial response with replayed: true and MUST NOT dispatch a second provider evaluation or record a second consumption or cost event. Reusing the key with a different creative_manifest, account, or feature_ids payload returns IDEMPOTENCY_CONFLICT. The provider MUST retain the replay record for at least 24 hours. Keys MUST be unique per (provider, request) pair to prevent cross-provider correlation. This field becomes required in AdCP 4.0; use a fresh UUID v4 for each logical evaluation.',
            max_length=255,
            min_length=16,
            pattern='^[A-Za-z0-9_.:-]{16,255}$',
        ),
    ] = None
    creative_manifest: Annotated[
        creative_manifest_1.CreativeManifest,
        Field(
            description='The canonical creative manifest to evaluate. In 3.2 it contains `format_kind`, optional `format_option_ref`, and typed assets. The deprecated named `format_id` branch remains available only for older 3.x peers.'
        ),
    ]
    feature_ids: Annotated[
        list[str] | None,
        Field(
            description='Optional filter to specific features. If omitted, returns all available features.',
            min_length=1,
        ),
    ] = None
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            description='Account for billing this evaluation. Required when the governance agent charges per evaluation.'
        ),
    ] = None
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Optional webhook configuration for async terminal completion/failure notifications. A submitted acknowledgement remains pollable through get_task_status whether or not this field is present. If the provider accepts this field and returns status: submitted, it MUST deliver at least the terminal completion or failure notification to the configured URL. If it cannot honor the webhook channel, it MUST reject the request instead of silently downgrading delivery.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The request message of a task in the pinned bundle's task registry.

A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is. issubclass(model, AdcpRequest) is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.

Each accessor returns the field's value, or None when this tool's schema declares no such field. Only 49 of the 87 request schemas declare an account and only 43 an idempotency_key, so asking the request is what replaces getattr(req, "account", None) against Any at the boundary.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var account : AccountReference1 | AccountReference2 | None
var context : ContextObject | None
var creative_manifest : CreativeManifest
var ext : ExtensionObject | None
var feature_ids : list[str] | None
var idempotency_key : str | None
var model_config
var push_notification_config : PushNotificationConfig | None

Inherited members

class HtmlContent (**data: Any)
Expand source code
class HtmlAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['html'],
        Field(
            description='Discriminator identifying this as an HTML asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'html'
    content: Annotated[str, Field(description='HTML content')]
    version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None
    accessibility: Annotated[
        Accessibility | None,
        Field(description='Self-declared accessibility properties for this opaque creative'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accessibility : Accessibility | None
var asset_type : Literal['html']
var content : str
var model_config
var provenance : Provenance | None
var version : str | None

Inherited members

class ImageContent (**data: Any)
Expand source code
class ImageAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['image'],
        Field(
            description='Discriminator identifying this as an image asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'image'
    url: Annotated[AnyUrl, Field(description='URL to the image asset')]
    width: Annotated[SchemaInt, Field(description='Width in pixels', ge=1)]
    height: Annotated[SchemaInt, Field(description='Height in pixels', ge=1)]
    file_size_bytes: Annotated[
        SchemaInt | None,
        Field(
            description='Image file size in bytes. Required by agents that advertise a max_file_size_kb constraint.',
            ge=1,
        ),
    ] = None
    pixel_ratio: Annotated[
        StrictFloat | None,
        Field(
            description='Intrinsic pixels per logical render pixel (for example `2` for a 600×500 image intended to render at 300×250). Optional because a validator can infer the ratio when the target format declares logical dimensions. When supplied, it MUST agree with both `width / logical_width` and `height / logical_height`; it is never a substitute for the intrinsic `width` and `height` fields.',
            gt=0.0,
        ),
    ] = None
    state_id: Annotated[
        str | None,
        Field(
            description='Binding used only when this image populates a `seller_rendered_stateful_display` `state_canvases` slot. It MUST match one declared `states[].state_id` (semantic validators resolve it). Omit for ordinary image slots.'
        ),
    ] = None
    breakpoint_id: Annotated[
        str | None,
        Field(
            description='Binding used only when this image populates a `seller_rendered_stateful_display` `state_canvases` slot. It MUST match one breakpoint declared on the selected state (semantic validators resolve it). Omit for ordinary image slots.'
        ),
    ] = None
    focal_point: Annotated[
        list[FocalPointItem] | None,
        Field(
            description="Normalized `[x, y]` coordinates (0–1 from top-left) of the image's visual anchor. Seller-side renderers crop toward the focal point when deriving renditions across breakpoints and aspect ratios; absent, cropping falls back to center-weighted defaults.",
            max_length=2,
            min_length=2,
        ),
    ] = None
    format: Annotated[
        str | None, Field(description='Image file format (jpg, png, gif, webp, etc.)')
    ] = None
    alt_text: Annotated[str | None, Field(description='Alternative text for accessibility')] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var alt_text : str | None
var asset_type : Literal['image']
var breakpoint_id : str | None
var file_size_bytes : int | None
var focal_point : list[FocalPointItem] | None
var format : str | None
var height : int
var model_config
var pixel_ratio : float | None
var provenance : Provenance | None
var state_id : str | None
var url : pydantic.networks.AnyUrl
var width : int

Inherited members

class JavascriptContent (**data: Any)
Expand source code
class JavascriptAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['javascript'],
        Field(
            description='Discriminator identifying this as a JavaScript asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'javascript'
    content: Annotated[str, Field(description='JavaScript content')]
    module_type: Annotated[
        javascript_module_type.JavascriptModuleType | None,
        Field(description='JavaScript module type'),
    ] = None
    accessibility: Annotated[
        Accessibility | None,
        Field(description='Self-declared accessibility properties for this opaque creative'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accessibility : Accessibility | None
var asset_type : Literal['javascript']
var content : str
var model_config
var module_type : JavascriptModuleType | None
var provenance : Provenance | None

Inherited members

class LegacyListCreativeFormatsRequest (**data: Any)
Expand source code
class ListCreativeFormatsRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            deprecated=True,
            description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Return only these specific named-format IDs (for example, from a 3.x get_products response). Use canonical-format discovery in 4.0.',
            min_length=1,
        ),
    ] = None
    asset_types: Annotated[
        list[asset_content_type.AssetContentType] | None,
        Field(
            description="Filter to formats that include these asset types. For third-party tags, search for 'html' or 'javascript'. For published-post reference formats, search for 'published_post'. E.g., ['image', 'text'] returns formats with images and text, ['javascript'] returns formats accepting JavaScript tags.",
            min_length=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum width in pixels (inclusive). Returns formats where ANY render has width <= this value. For multi-render formats, matches if at least one render fits.'
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum height in pixels (inclusive). Returns formats where ANY render has height <= this value. For multi-render formats, matches if at least one render fits.'
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum width in pixels (inclusive). Returns formats where ANY render has width >= this value.'
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum height in pixels (inclusive). Returns formats where ANY render has height >= this value.'
        ),
    ] = None
    is_responsive: Annotated[
        StrictBool | None,
        Field(
            description='Filter for responsive formats that adapt to container size. When true, returns formats without fixed dimensions.'
        ),
    ] = None
    name_search: Annotated[
        str | None, Field(description='Search for formats by name (case-insensitive partial match)')
    ] = None
    publisher_domain: Annotated[
        str | None,
        Field(
            deprecated=True,
            description="Deprecated compatibility filter for older 3.x callers. A compatibility implementation MAY project publisher-origin or community-catalog declarations obtained through the registry publisher lookup, but MUST NOT synthesize a publisher catalog from seller products. New callers use `GET /api/registry/publisher?domain=...` for publisher acceptance and `get_products` for this seller's deliverability. The pattern below is a syntactic floor, not an SSRF guard.",
            pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$',
        ),
    ] = None
    property_id: Annotated[
        property_id_1.PropertyId | None,
        Field(
            description="Filter to formats supported on the named property within the publisher's catalog. Resolves to a property in the publisher's `adagents.json` `properties[]`; the agent returns only `formats[]` entries whose `applies_to_property_ids` includes this property (or entries with no scope, which apply to all properties). Typically used in combination with `publisher_domain`."
        ),
    ] = None
    wcag_level: Annotated[
        wcag_level_1.WcagLevel | None,
        Field(
            description='Filter to formats that meet at least this WCAG conformance level (A < AA < AAA)'
        ),
    ] = None
    disclosure_positions: Annotated[
        list[disclosure_position.DisclosurePosition] | None,
        Field(
            description="Filter to formats that support all of these disclosure positions. When a format has disclosure_capabilities, match against those positions. Otherwise fall back to supported_disclosure_positions. Use to find formats compatible with a brief's compliance requirements.",
            min_length=1,
        ),
    ] = None
    disclosure_persistence: Annotated[
        list[disclosure_persistence_1.DisclosurePersistence] | None,
        Field(
            description='Filter to formats where each requested persistence mode is supported by at least one position in disclosure_capabilities. Different positions may satisfy different modes. Use to find formats compatible with jurisdiction-specific persistence requirements (e.g., continuous for EU AI Act).',
            min_length=1,
        ),
    ] = None
    output_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Filter to formats whose output_format_ids includes any of these format IDs. Returns formats that can produce these outputs — inspect each result's input_format_ids to see what inputs they accept.",
            min_length=1,
        ),
    ] = None
    input_format_ids: Annotated[
        list[format_id.FormatReferenceStructuredObject] | None,
        Field(
            description="Filter to formats whose input_format_ids includes any of these format IDs. Returns formats that accept these creatives as input — inspect each result's output_format_ids to see what they can produce.",
            min_length=1,
        ),
    ] = None
    account: Annotated[
        account_ref.AccountReference | None,
        Field(
            deprecated=True,
            description="**DEPRECATED with `list_creative_formats` in 3.2. Removed at 4.0.** Use `get_products` with `account`; each `Product.format_options[]` lists the formats this seller can deliver for that account. *Legacy 3.x behavior:* scopes the returned formats to this account. Sellers that keep account-specific format catalogs (including sandbox accounts) return that account's formats; sellers with a single catalog MAY ignore this field.",
        ),
    ] = None
    pagination: pagination_request.PaginationRequest | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The request message of a task in the pinned bundle's task registry.

A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is. issubclass(model, AdcpRequest) is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.

Each accessor returns the field's value, or None when this tool's schema declares no such field. Only 49 of the 87 request schemas declare an account and only 43 an idempotency_key, so asking the request is what replaces getattr(req, "account", None) against Any at the boundary.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_types : list[AssetContentType] | None
var context : ContextObject | None
var disclosure_persistence : list[DisclosurePersistence] | None
var disclosure_positions : list[DisclosurePosition] | None
var ext : ExtensionObject | None
var input_format_ids : list[FormatReferenceStructuredObject] | None
var is_responsive : bool | None
var max_height : int | None
var max_width : int | None
var min_height : int | None
var min_width : int | None
var model_config
var output_format_ids : list[FormatReferenceStructuredObject] | None
var pagination : PaginationRequest | None
var property_id : PropertyId | None
var wcag_level : WcagLevel | None

Instance variables

var account : AccountReference1 | AccountReference2 | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var adcp_major_version : int | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var format_ids : list[FormatReferenceStructuredObject] | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var publisher_domain : str | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class LegacyListCreativeFormatsResponse (**data: Any)
Expand source code
class ListCreativeFormatsResponse(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    formats: Annotated[
        list[format.Format],
        Field(
            deprecated=True,
            description="Deprecated named-format definitions projected for older 3.x callers. This list is neither the publisher acceptance catalog nor the seller's canonical product deliverability contract.",
        ),
    ]
    source: Annotated[
        Source | None,
        Field(
            deprecated=True,
            description='Deprecated compatibility provenance. `publisher` means publisher-origin catalog; `aao_mirror` means community catalog; `agent_derived` is retained only to parse historical 3.x responses and MUST NOT be produced by a new 3.2 implementation because seller products are not publisher authority.',
        ),
    ] = None
    creative_agents: Annotated[
        list[CreativeAgent] | None,
        Field(
            deprecated=True,
            description="Deprecated recursive discovery projection retained for historical 3.x responses. New buyers query the registry's canonical creative capability index and confirm candidates with get_adcp_capabilities; they do not recursively walk agent-provided lists.",
        ),
    ] = None
    errors: Annotated[
        list[error.Error] | None,
        Field(description='Task-specific errors and warnings (e.g., format availability issues)'),
    ] = None
    pagination: pagination_response.PaginationResponse | None = None
    sandbox: Annotated[
        StrictBool | None,
        Field(description='When true, this response contains simulated data from sandbox mode.'),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var model_config
var pagination : PaginationResponse | None
var sandbox : bool | None
var status : TaskStatus | None

Instance variables

var adcp_major_version : int | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var creative_agents : list[CreativeAgent] | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var formats : list[Format]
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.
var source : Source | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class ListCreativesRequest (**data: Any)
Expand source code
class ListCreativesRequest(_LegacyListCreativesRequest, CanonicalBoundaryModel):
    """Canonical creative read request with legacy field selection rejected."""

    filters: CreativeFilters | None = None

    @field_validator("fields")
    @classmethod
    def _reject_legacy_fields(cls, value: Any) -> Any:
        if value and any(
            is_legacy_creative_identity_key(getattr(item, "value", item)) for item in value
        ):
            raise ValueError(
                "format_id and format_ids are unavailable on the canonical list_creatives API"
            )
        return value

Canonical creative read request with legacy field selection rejected.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var filters : CreativeFilters | None
var model_config

Inherited members

class ListCreativesResponse (**data: Any)
Expand source code
class ListCreativesResponse(_LegacyListCreativesResponse, CanonicalBoundaryModel):
    """Canonical creative listing; rows are canonical listed creatives."""

    creatives: list[Creative]

Canonical creative listing; rows are canonical listed creatives.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var creatives : list[Creative]
var model_config

Inherited members

class MarkdownAsset (**data: Any)
Expand source code
class MarkdownAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['markdown'],
        Field(
            description='Discriminator identifying this as a markdown asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'markdown'
    content: Annotated[
        str,
        Field(
            description='Markdown content following CommonMark spec with optional GitHub Flavored Markdown extensions'
        ),
    ]
    language: Annotated[
        str | None,
        Field(
            description='Optional language claim for this markdown. In a materialized creative localization variant, localized-creative-asset.json requires this value to use /schemas/core/locale-tag.json and conformance requires exact equality with the enclosing variant locale. General non-localized assets retain the legacy unconstrained string for compatibility.'
        ),
    ] = None
    markdown_flavor: Annotated[
        markdown_flavor_1.MarkdownFlavor | None,
        Field(
            description='Markdown flavor used. CommonMark for strict compatibility, GFM for tables/task lists/strikethrough.'
        ),
    ] = markdown_flavor_1.MarkdownFlavor.commonmark
    allow_raw_html: Annotated[
        StrictBool | None,
        Field(
            description='Whether raw HTML blocks are allowed in the markdown. False recommended for security.'
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var allow_raw_html : bool | None
var asset_type : Literal['markdown']
var content : str
var language : str | None
var markdown_flavor : MarkdownFlavor | None
var model_config

Inherited members

class PixelTrackerAsset (**data: Any)
Expand source code
class PixelTrackerAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['pixel_tracker'],
        Field(
            description='Discriminator identifying this as a renderer-fired pixel tracker asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'pixel_tracker'
    event: Annotated[
        pixel_tracking_event.PixelTrackingEvent,
        Field(
            description="Which event this tracker fires on. The event enum maps its first four measurement values to IAB OpenRTB Native 1.2 event types 1-4 and adds explicit AdCP events for renderer behavior that Native does not assign a standard event type:\n- `impression` (IAB type 1) — fires when the ad is served. Covers both `imptrackers[]` and `jstracker` from the IAB shape, distinguished by `method`.\n- `viewable_mrc_50` (IAB type 2) — IAB MRC viewable, 50% pixels for ≥1 second.\n- `viewable_mrc_100` (IAB type 3) — IAB MRC viewable, 100% pixels for ≥1 second.\n- `viewable_video_50` (IAB type 4) — video-specific viewable, 50% pixels for ≥2 seconds. Native type 4 does not require audio. On video_hosted; ignored on image/html5.\n- `audible_video_complete` (AdCP-defined) — video reached 100% completion with audio on. Native reserves event types 500+ for exchange-specific use and does not assign this event a standard numeric type. Meaningful on non-VAST video formats where audible-complete is measured but VAST `<TrackingEvents>` is not the wire format; VAST formats use `vast_tracker` with `vast_event: complete` plus a separate audible tracker instead.\n- `click` — fires when the user clicks the creative (`link.clicktrackers[]`).\n- `custom` — adopter-defined event for anything not in the standardized enum. MUST also set `custom_event_name`; it can represent Native's exchange-specific 500+ range or another qualified vendor event without assigning an IAB numeric identity."
        ),
    ]
    method: Annotated[
        Method | None,
        Field(
            description="How the tracker URL is invoked at serve time:\n- `img` — fired as an image pixel (HTTP GET with `<img>`-like semantics; no JS execution)\n- `js` — fired as a script include (renderer evaluates the URL's response as JavaScript)\n\nMatches IAB OpenRTB Native 1.2 method enum (1=img, 2=js). `js` MUST only be used by sellers whose renderer supports JavaScript trackers; sellers without JS-tracker support MUST reject `method: js` declarations at sync_creatives time with `CREATIVE_REJECTED` carrying the reason."
        ),
    ] = Method.img
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Tracker URL fired when `event` occurs. Macro processing and encoding follow an attached occurrence declaration; absent declarations retain the legacy universal-macro path.'
        ),
    ]
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='One declaration per token occurrence in `url`; declaration_id values MUST be unique and locations MUST resolve. When omitted, legacy behavior applies.',
            min_length=1,
        ),
    ] = None
    custom_event_name: Annotated[
        str | None,
        Field(
            description='REQUIRED when `event` is `custom`; otherwise MUST be absent. Adopter-defined event name. When tracker execution is undeclared, an unknown custom event is a forward-compatible probe and the seller silently no-ops instead of rejecting the creative. An effective tracker_execution_contract overrides that legacy fallback: with complete:true an unlisted custom selector is unsupported and rejects compatibility with tracker_contract_mismatch; a listed custom selector is an affirmative accept-and-initiate commitment.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['pixel_tracker']
var custom_event_name : str | None
var event : PixelTrackingEvent
var macro_declarations : list[MacroDeclaration] | None
var method : Method | None
var model_config
var provenance : Provenance | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4

Inherited members

class PlacementPresentationDocument (**data: Any)
Expand source code
class PlacementPresentationDocument(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    schema_version: Literal['1.0'] = '1.0'
    canvas: Canvas
    creative_slot: Annotated[
        CreativeSlot,
        Field(
            description='Rectangle into which the selected creative render is fitted and clipped without changing its manifest or renderer.'
        ),
    ]
    decorations: Annotated[
        list[BoxDecoration | TextDecoration | ImageDecoration] | None, Field(max_length=100)
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var canvas : Canvas
var creative_slot : CreativeSlot
var decorations : list[BoxDecoration | TextDecoration | ImageDecoration] | None
var model_config
var schema_version : Literal['1.0']

Inherited members

class PlacementPresentationReference (**data: Any)
Expand source code
class PlacementPresentationReference(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    uri: Annotated[
        AnyUrl,
        Field(
            description='Publisher-controlled HTTPS URL for the presentation metadata. Consumers MUST apply the same SSRF, redirect, response-size, timeout, and DNS-rebinding protections used for format_schema fetches.'
        ),
    ]
    digest: Annotated[
        str,
        Field(
            description='SHA-256 content digest. Consumers cache by uri@digest and MUST fail closed on a digest mismatch.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ]
    media_type: Annotated[
        Literal['application/vnd.adcp.placement-presentation+json'],
        Field(description='Media type of the referenced declarative presentation document.'),
    ] = 'application/vnd.adcp.placement-presentation+json'
    schema_version: Annotated[
        Literal['1.0'],
        Field(
            description='Version of /schemas/core/placement-presentation.json used to validate and compose the referenced document.'
        ),
    ] = '1.0'

    @field_validator('uri')
    @classmethod
    def _require_https_uri(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https':
            raise ValueError('uri must use https')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var digest : str
var media_type : Literal['application/vnd.adcp.placement-presentation+json']
var model_config
var schema_version : Literal['1.0']
var uri : pydantic.networks.AnyUrl

Inherited members

class LegacyPreviewCreativeRequest (**data: Any)
Expand source code
class PreviewCreativeRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    request_type: Annotated[
        RequestType,
        Field(
            description="Preview mode. 'single' previews one creative manifest. 'batch' previews multiple creatives in one call. 'variant' replays a post-flight variant by ID."
        ),
    ]
    creative_manifest: Annotated[
        creative_manifest_1.CreativeManifest | None,
        Field(
            description='Complete creative manifest with all required assets for the format. In single mode, provide exactly one of creative_manifest or creative_id. Also accepted per item in batch mode.'
        ),
    ] = None
    target_capability_id: Annotated[
        str | None,
        Field(
            description="Canonical preview-operation selector. Identifies one get_adcp_capabilities creative.supported_formats[].capability_id entry whose operations contains preview. In single mode it selects the renderer for this request; in batch mode it is the default for items that omit their own target_capability_id. When omitted, the agent MAY resolve the renderer only if exactly one advertised preview capability satisfies the manifest's canonical declaration; zero matches or multiple matches MUST be rejected with FORMAT_NOT_SUPPORTED rather than choosing nondeterministically. Mutually exclusive with deprecated format_id.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ] = None
    format_id: Annotated[
        format_id_1.FormatReferenceStructuredObject | None,
        Field(
            deprecated=True,
            description='**DEPRECATED in 3.2.** Legacy named-format preview route. New requests select an advertised preview renderer with target_capability_id and carry portable format identity in creative_manifest_1.format_kind plus optional creative_manifest_1.format_option_ref.',
        ),
    ] = None
    inputs: Annotated[
        list[Input] | None,
        Field(
            description='Array of input sets for generating multiple preview variants. Each input set defines macros and context values for one preview rendering. Used in single mode.',
            min_length=1,
        ),
    ] = None
    template_id: Annotated[
        str | None,
        Field(description='Specific template ID for custom format rendering. Used in single mode.'),
    ] = None
    quality: Annotated[
        creative_quality.CreativeQuality | None,
        Field(
            description="Render quality. 'draft' produces fast, lower-fidelity renderings. 'production' produces full-quality renderings. In batch mode, sets the default for all requests (individual items can override)."
        ),
    ] = None
    output_format: Annotated[
        preview_output_format.PreviewOutputFormat | None,
        Field(
            description="Output format. 'url' returns preview_url (iframe-embeddable URL), 'html' returns preview_html (raw HTML). In batch mode, sets the default for all requests (individual items can override). Default: 'url'."
        ),
    ] = preview_output_format.PreviewOutputFormat.url
    item_limit: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum number of catalog items to render per preview variant. Used in single mode. Creative agents SHOULD default to a reasonable sample when omitted and the catalog is large.',
            ge=1,
        ),
    ] = None
    requests: Annotated[
        list[Request] | None,
        Field(
            description="Array of preview requests (1-50 items). Required when request_type is 'batch'. Each item follows the single request structure.",
            max_length=50,
            min_length=1,
        ),
    ] = None
    variant_id: Annotated[
        str | None,
        Field(
            description="Agent-assigned AdCP served-execution identifier from get_creative_delivery. Required when request_type is 'variant'. It is agent-unique when the source agent advertises creative.supports_revisions; for legacy agents the published scope remains agent plus creative, and callers SHOULD also send creative_id to disambiguate reused values."
        ),
    ] = None
    creative_id: Annotated[
        str | None,
        Field(
            description='Creative-library identifier. In single mode, previews the stored canonical creative without requiring the caller to reconstruct its manifest. Also available as context in variant mode.'
        ),
    ] = None
    allow_async: Annotated[
        StrictBool | None,
        Field(
            description="Opt in to an asynchronous preview response. When true, the creative agent MAY return status 'submitted' with a task_id only when rendering has been handed to a queue or external renderer and will continue after the request connection is released. Active processing on an open connection uses working progress instead. The buyer polls get_task_status for completion. When false or absent, the agent MUST return a synchronous preview response or a terminal protocol error; it MUST NOT return the submitted shape. This field applies to preview_creative only; build_creative already defines its own async lifecycle."
        ),
    ] = False
    push_notification_config: Annotated[
        push_notification_config_1.PushNotificationConfig | None,
        Field(
            description='Optional webhook configuration for terminal completion/failure notifications when allow_async is true and preview_creative returns a submitted task envelope. Submitted tasks remain pollable through get_task_status whether or not this field is present. If the agent accepts this configuration and returns submitted, it MUST deliver at least the terminal notification; if it cannot honor the webhook, it MUST return a structured error. Presence of this field alone MUST NOT cause asynchronous execution.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The request message of a task in the pinned bundle's task registry.

A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is. issubclass(model, AdcpRequest) is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.

Each accessor returns the field's value, or None when this tool's schema declares no such field. Only 49 of the 87 request schemas declare an account and only 43 an idempotency_key, so asking the request is what replaces getattr(req, "account", None) against Any at the boundary.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var allow_async : bool | None
var context : ContextObject | None
var creative_id : str | None
var creative_manifest : CreativeManifest | None
var ext : ExtensionObject | None
var format_id : FormatReferenceStructuredObject | None
var inputs : list[Input] | None
var item_limit : int | None
var model_config
var output_format : PreviewOutputFormat | None
var push_notification_config : PushNotificationConfig | None
var quality : CreativeQuality | None
var request_type : RequestType
var requests : list[Request] | None
var target_capability_id : str | None
var template_id : str | None
var variant_id : str | None

Inherited members

class LegacyPreviewCreativeSingleResponse (**data: Any)
Expand source code
class PreviewCreativeResponse1(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    response_type: Literal['single'] = 'single'
    previews: Annotated[list[Preview], Field(min_length=1)]
    quality_used: creative_quality_1.CreativeQuality | None = None
    interactive_url: AnyUrl | None = None
    expires_at: AwareDatetime | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var interactive_url : pydantic.networks.AnyUrl | None
var model_config
var previews : list[Preview]
var quality_used : CreativeQuality | None
var response_type : Literal['single']

Inherited members

class LegacyPreviewCreativeBatchResponse (**data: Any)
Expand source code
class PreviewCreativeResponse2(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    response_type: Literal['batch'] = 'batch'
    results: Annotated[list[Result], Field(min_length=1)]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var response_type : Literal['batch']
var results : list[Result]

Inherited members

class LegacyPreviewCreativeVariantResponse (**data: Any)
Expand source code
class PreviewCreativeResponse3(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    response_type: Literal['variant'] = 'variant'
    variant_id: str
    creative_id: str | None = None
    previews: Annotated[list[Preview3], Field(min_length=1)]
    manifest: creative_manifest_1.CreativeManifest | None = None
    expires_at: AwareDatetime | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var creative_id : str | None
var expires_at : pydantic.types.AwareDatetime | None
var ext : ExtensionObject | None
var manifest : adcp.types._forward_compat._ReadbackCreativeManifest | None
var model_config
var previews : list[Preview3]
var response_type : Literal['variant']
var variant_id : str

Instance variables

var adcp_major_version : int | None
Expand source code
def __get__(self, obj: BaseModel | None, obj_type: type[BaseModel] | None = None) -> Any:
    if obj is None:
        if self.wrapped_property is not None:
            return self.wrapped_property.__get__(None, obj_type)
        raise AttributeError(self.field_name)

    warnings.warn(self.msg, DeprecationWarning, stacklevel=2)

    if self.wrapped_property is not None:
        return self.wrapped_property.__get__(obj, obj_type)
    return obj.__dict__[self.field_name]

Read-only data descriptor used to emit a runtime deprecation warning before accessing a deprecated field.

Attributes
-----=
msg
The deprecation message to be emitted.
wrapped_property
The property instance if the deprecated field is a computed field, or None.
field_name
The name of the field being deprecated.

Inherited members

class PreviewRendererMetadata (**data: Any)
Expand source code
class PreviewRendererMetadata(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    renderer_id: Annotated[
        str, Field(description='Stable implementation identifier.', min_length=1)
    ]
    version: Annotated[
        str,
        Field(
            description='Exact semantic version of the renderer implementation.',
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$',
        ),
    ]
    export: Annotated[
        str,
        Field(
            description='Renderer export or entry-point name used for this render.', min_length=1
        ),
    ]
    rendering_origin: Annotated[
        RenderingOrigin,
        Field(
            description='Informational implementation origin copied from the selected route. It does not grant authority.'
        ),
    ]
    tracking_suppressed: Annotated[
        StrictBool,
        Field(
            description='True only when the produced output cannot initiate impression, click, billing, conversion, viewability, or asset-fetch side effects. Renderers that retain any remote asset URL or navigation MUST emit false.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var export : str
var model_config
var renderer_id : str
var rendering_origin : RenderingOrigin
var tracking_suppressed : bool
var version : str

Inherited members

class ReferenceRendererProvenance (**data: Any)
Expand source code
class Provenance(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    source_repository: Annotated[
        AnyUrl,
        Field(
            description='Allowlisted source repository that the npm provenance attestation MUST identify.'
        ),
    ]
    workflow_path: Annotated[
        str,
        Field(
            description='Repository-relative GitHub Actions workflow path that npm provenance buildDefinition.externalParameters.workflow.path MUST identify.',
            pattern='^\\.github/workflows/[A-Za-z0-9._/-]+\\.ya?ml$',
        ),
    ]

    @field_validator('source_repository')
    @classmethod
    def _require_github_source_repository(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https' or value.host != 'github.com' or value.port != 443:
            raise ValueError('source_repository must use https://github.com/')
        if value.username is not None or value.password is not None:
            raise ValueError('source_repository must not contain credentials')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var source_repository : pydantic.networks.AnyUrl
var workflow_path : str

Inherited members

class PublishedPostAsset (**data: Any)
Expand source code
class PublishedPostAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['published_post'],
        Field(
            description='Discriminator identifying this as a published-post reference asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'published_post'
    post_url: Annotated[
        AnyUrl | None,
        Field(
            description='Canonical URL for the published post. Preferred when the platform exposes a stable public or authenticated URL.'
        ),
    ] = None
    platform: Annotated[
        str | None,
        Field(
            description="Optional platform or publisher namespace for the referenced post. Informational unless the seller's product declaration or platform extension narrows the accepted values."
        ),
    ] = None
    platform_post_id: Annotated[
        str | None,
        Field(
            description='Optional platform-native post identifier when a URL alone is not stable or not available. Buyers SHOULD include `platform` when using `platform_post_id` without `post_url`, unless the product or format declaration already narrows the platform. Platform-specific identifier semantics belong in platform_extensions; this field is only an opaque reference.'
        ),
    ] = None
    identity_ref: Annotated[
        IdentityRef | None,
        Field(
            description='Optional identity hint for the authoring handle/page/channel that owns the post. Sellers MUST verify authorization from platform state; buyers MUST NOT use this object as proof of authorization.'
        ),
    ] = None
    published_at: Annotated[
        AwareDatetime | None,
        Field(description='When the referenced post was originally published, if known.'),
    ] = None
    reference_authorization: Annotated[
        ReferenceAuthorization | None,
        Field(
            description='Server-emitted, seller-observed authorization state for the referenced post or identity. Sellers MAY return this object on read surfaces. On write requests, sellers MUST ignore buyer-supplied `reference_authorization.status` and other authorization-state claims unless a platform extension explicitly defines a signed proof shape and the seller verifies that proof.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this reference asset, overrides manifest-level provenance.'
        ),
    ] = None

    @model_validator(mode='after')
    def _require_schema_required_group(self) -> PublishedPostAsset:
        # ``required`` asks whether the caller supplied the field, which is what
        # model_fields_set answers. An explicit null is a supplied value — on a
        # mutation input it is the command to clear — and a default the caller
        # never sent is not.
        for group in (('post_url',), ('platform_post_id',),):
            if all(name in self.model_fields_set for name in group):
                return self
        raise ValueError(
            'PublishedPostAsset requires at least one of these field groups: post_url | platform_post_id'
        )

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['published_post']
var identity_ref : IdentityRef | None
var model_config
var platform : str | None
var platform_post_id : str | None
var post_url : pydantic.networks.AnyUrl | None
var provenance : Provenance | None
var published_at : pydantic.types.AwareDatetime | None
var reference_authorization : ReferenceAuthorization | None

Inherited members

class PublisherDesignatedPreviewProvider (**data: Any)
Expand source code
class PublisherDesignatedPreviewProvider(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    agent_url: Annotated[
        AnyUrl,
        Field(
            description='HTTPS URL of the delegated creative-agent endpoint. Buyers call get_adcp_capabilities and preview_creative on this endpoint. They MUST allow only public IPs, pin DNS resolution through connection, refuse redirects, cap time and response size, and attach provider credentials only after exact normalized-origin binding.'
        ),
    ]
    authority: Annotated[
        Literal['publisher_designated'],
        Field(
            description="Explicitly states that authority comes from the publisher-hosted placement declaration. The provider's rendering_origin metadata is informational and remains non-authoritative elsewhere."
        ),
    ] = 'publisher_designated'
    routes: Annotated[list[Route], Field(min_length=1)]

    @field_validator('agent_url')
    @classmethod
    def _require_https_agent_url(cls, value: AnyUrl) -> AnyUrl:
        if value.scheme != 'https':
            raise ValueError('agent_url must use https')
        return value

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var agent_url : pydantic.networks.AnyUrl
var authority : Literal['publisher_designated']
var model_config
var routes : list[Route]

Inherited members

class ReferenceRenderer (**data: Any)
Expand source code
class ReferenceRenderer(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    runtime: Annotated[
        Literal['browser-esm'],
        Field(
            description='Execution contract for the referenced package. browser-esm means a browser-safe ECMAScript module that accepts canonical manifest data and returns an inert presentation without Node.js APIs, ambient credentials, delivery tracking, or undeclared network access. Non-JavaScript clients use a hosted preview_creative provider or display the manifest.'
        ),
    ] = 'browser-esm'
    package: Annotated[
        str,
        Field(
            description='npm package name, scoped or unscoped. The package is resolved from the npm registry; the AdCP registry does not proxy its executable contents.',
            pattern='^(?:@[a-z0-9][a-z0-9._~-]*/)?[a-z0-9][a-z0-9._~-]*$',
        ),
    ]
    version: Annotated[
        str,
        Field(
            description='Exact semantic version. Ranges and tags such as latest are forbidden so the registry entry is reproducible. Package semantic versioning identifies the pinned distribution artifact; it is independent of any one format revision because one package may expose renderers for multiple formats.',
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$',
        ),
    ]
    export: Annotated[
        str,
        Field(
            description="Named package export that implements the renderer contract for this enclosing format entry. Compatibility is bound at the export-to-entry edge, not to matching version labels: registry review and contract fixtures verify that the export implements the entry's input contract. When that input contract changes, the registry MUST rerun those fixtures and MAY retain the existing export and package pin when they still pass. One package version MAY expose different named exports for different formats or input contracts.",
            min_length=1,
        ),
    ]
    format_revision: Annotated[
        str | None,
        Field(
            deprecated=True,
            description="Deprecated compatibility annotation retained for previously published registry entries. Renderer package versions and community format revisions have independent lifecycles, so consumers MUST NOT require this value to equal the enclosing entry's format_revision or use matching values as evidence of compatibility. Registry review and contract fixtures bind the named export to the enclosing format's input contract. New entries SHOULD omit this field.",
            pattern='^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$',
        ),
    ] = None
    integrity: Annotated[
        str,
        Field(
            description='Subresource Integrity value for the exact npm package tarball. Consumers MUST compare this value before loading code, require the provenance subject digest to match the same tarball, and fail closed on mismatch.',
            pattern='^(?:sha256-[A-Za-z0-9+/]{43}=|sha384-[A-Za-z0-9+/]{64}|sha512-[A-Za-z0-9+/]{86}==)$',
        ),
    ]
    provenance: Provenance

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var export : str
var format_revision : str | None
var integrity : str
var model_config
var package : str
var provenance : Provenance
var runtime : Literal['browser-esm']
var version : str

Inherited members

class PreviewRenderingOrigin (*args, **kwds)
Expand source code
class RenderingOrigin(StrEnum):
    platform_native = 'platform_native'
    agent_approximation = 'agent_approximation'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var agent_approximation
var platform_native
class Renders (**data: Any)
Expand source code
class Renders(AdCPBaseModel):
    role: Annotated[
        str,
        Field(
            description="Semantic role of this rendered piece (e.g., 'primary', 'companion', 'mobile_variant')"
        ),
    ]
    parameters_from_format_id: Annotated[
        StrictBool | None,
        Field(
            description='When true, parameters for this render (dimensions and/or duration) are specified in the format_id. Used for template formats that accept parameters. Mutually exclusive with specifying dimensions object explicitly.'
        ),
    ] = None
    dimensions: Annotated[
        Dimensions,
        Field(
            description='Dimensions for this rendered piece. Defaults to pixels when unit is absent.'
        ),
    ]

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var dimensions : Dimensions
var model_config
var parameters_from_format_id : bool | None
var role : str

Inherited members

class Responsive (**data: Any)
Expand source code
class Responsive(AdCPBaseModel):
    width: StrictBool
    height: StrictBool

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var height : bool
var model_config
var width : bool

Inherited members

class PublisherPreviewRoute (**data: Any)
Expand source code
class Route(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    format_option_id: Annotated[
        str,
        Field(
            description='Format option in this adagents.json placement for which the delegation applies. It MUST resolve through the same-file top-level formats[] catalog or an inline placement format declaration.',
            min_length=1,
        ),
    ]
    capability_id: Annotated[
        str,
        Field(
            description="Agent-local preview capability advertised by the delegated provider. The provider's canonical format declaration MUST satisfy the resolved placement format option.",
            pattern='^[a-zA-Z0-9_-]+$',
        ),
    ]
    covers_placement_presentation: Annotated[
        StrictBool | None,
        Field(
            description="True only when the publisher delegates both creative rendering and the complete placement-specific frame to this route. When false or omitted, consumers compose any presentation_ref around the provider's creative render."
        ),
    ] = False

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var capability_id : str
var covers_placement_presentation : bool | None
var format_option_id : str
var model_config

Inherited members

class SyncCreativesRequest (**data: Any)
Expand source code
class SyncCreativesRequest(_LegacySyncCreativesRequest, CanonicalBoundaryModel):
    """Canonical creative sync request; creatives are canonical assets."""

    creatives: list[CreativeAsset] = Field(min_length=1)  # type: ignore[assignment]

Canonical creative sync request; creatives are canonical assets.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var creatives : list[CreativeAsset]
var model_config

Inherited members

class SyncCreativesSuccessResponse (**data: Any)
Expand source code
class SyncCreativesResponse1(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    dry_run: bool | None = None
    creatives: list[Creative]
    sandbox: bool | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var creatives : list[Creative]
var dry_run : bool | None
var ext : ExtensionObject | None
var model_config
var sandbox : bool | None

Inherited members

class SyncCreativesErrorResponse (**data: Any)
Expand source code
class SyncCreativesResponse2(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow')
    errors: Annotated[list[error_1.Error], Field(min_length=1)]
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var errors : list[Error]
var ext : ExtensionObject | None
var model_config

Inherited members

class SyncCreativesSubmittedResponse (**data: Any)
Expand source code
class SyncCreativesResponse3(AdcpResponse, AdcpVersionEnvelope, ProtocolEnvelope):
    model_config = ConfigDict(extra='allow', validate_default=True)
    status: Literal[task_status_1.TaskStatus.submitted] = task_status_1.TaskStatus.submitted
    task_id: str
    message: Annotated[str, StringConstraints(max_length=2000)] | None = None
    errors: list[error_1.Error] | None = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None

The response message of a task in the pinned bundle's task registry.

A consumer holding one can route on task state, pick up an async task_id, split envelope from payload and log uniformly, before knowing which tool answered. Which makes one generic poll-to-terminal loop possible for all 77 tasks, where today each arm has no common type at all.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var context : ContextObject | None
var errors : list[Error] | None
var ext : ExtensionObject | None
var message : str | None
var model_config
var status : Literal[]
var task_id : str

Inherited members

class TextContent (**data: Any)
Expand source code
class TextAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['text'],
        Field(
            description='Discriminator identifying this as a text asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'text'
    content: Annotated[str, Field(description='Text content')]
    language: Annotated[
        str | None,
        Field(
            description='Optional language claim for this text. In a materialized creative localization variant, localized-creative-asset.json requires this value to use /schemas/core/locale-tag.json and conformance requires exact equality with the enclosing variant locale. General non-localized assets retain the legacy unconstrained string for compatibility.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['text']
var content : str
var language : str | None
var model_config
var provenance : Provenance | None

Inherited members

class UrlContent (**data: Any)
Expand source code
class UrlAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['url'],
        Field(
            description='Discriminator identifying this as a URL asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'url'
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='URL reference carrying plain, AdCP, IAB, or declared vendor macro syntax. Buyers preserve token delimiters; the authoritative declaration determines the processing operation and encoding.'
        ),
    ]
    url_type: Annotated[
        url_asset_type.UrlAssetType | None,
        Field(
            description='Mechanism a receiver uses to invoke this URL: `clickthrough` for a user destination, `ad_request` for a third-party display creative request, `tracker_pixel` for an event HTTP request, or `tracker_script` for a script include. SHOULD be present on every URL asset.'
        ),
    ] = None
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='One declaration per token occurrence in `url`; declaration_id values MUST be unique and every location MUST identify an existing occurrence. Absence retains legacy opaque transport behavior.',
            min_length=1,
        ),
    ] = None
    description: Annotated[
        str | None, Field(description='Description of what this URL points to')
    ] = None
    state_id: Annotated[
        str | None,
        Field(
            description='Binding used only when this URL populates a `seller_rendered_stateful_display` `state_click_urls` slot. It MUST match one declared `states[].state_id` (semantic validators resolve it); at most one entry per state. Omit for ordinary URL slots.'
        ),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['url']
var description : str | None
var macro_declarations : list[MacroDeclaration] | None
var model_config
var provenance : Provenance | None
var state_id : str | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4
var url_type : UrlAssetType | None

Inherited members

class VastAsset (root: RootModelRootType = PydanticUndefined, **data)
Expand source code
class VastAsset(RootModel[VastAsset3 | VastAsset4]):
    root: Annotated[
        VastAsset3 | VastAsset4,
        Field(
            description='VAST (Video Ad Serving Template) tag for third-party video or audio ad serving. Unlike a hosted media asset, a VAST tag carries no single `width`/`height`: a response can return multiple renditions and the player selects one at serve time. Standardized VAST audio support begins at 4.1 and uses MediaFile width and height values of 0; older audio-in-VAST versions are seller-declared legacy interoperability. Dimensional, duration, MIME-type, and codec constraints live on the format/requirements layer, not on this asset.',
            discriminator='delivery_type',
            title='VAST Asset',
        ),
    ]
    def __getattr__(self, name: str) -> Any:
        """Proxy attribute access to the wrapped type."""
        if name.startswith('_'):
            raise AttributeError(name)
        return getattr(self.root, name)

Usage Documentation

RootModel and Custom Root Types

A Pydantic BaseModel for the root object of the model.

Attributes
-----=
root
The root object of the model.
__pydantic_root_model__
Whether the model is a RootModel.
__pydantic_private__
Private fields in the model.
__pydantic_extra__
Extra fields in the model.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

  • pydantic.root_model.RootModel[Union[VastAsset3, VastAsset4]]
  • pydantic.root_model.RootModel
  • pydantic.main.BaseModel
  • typing.Generic

Class variables

var model_config
var root : VastAsset3 | VastAsset4
class VastTrackerAsset (**data: Any)
Expand source code
class VastTrackerAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['vast_tracker'],
        Field(
            description='Discriminator identifying this as a VAST tracker asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'vast_tracker'
    vast_event: Annotated[
        vast_tracking_event.VastTrackingEvent,
        Field(
            description='The VAST tracking event this URL fires on. Maps 1:1 to the VAST `Tracking event="..."` attribute inside `TrackingEvents`. MUST NOT be `impression` (belongs in the VAST `Impression` element — model as a `url` asset with `url_type: "tracker_pixel"`), `clickTracking` / `customClick` (belong in `VideoClicks`), `error` (VAST `Error` element), or any of `viewable` / `notViewable` / `viewUndetermined` / `measurableImpression` / `viewableImpression` (children of the VAST `ViewableImpression` element, not `TrackingEvents`).'
        ),
    ]
    url: Annotated[
        macro_bearing_url.MacroBearingUrl,
        Field(
            description='Tracker URL fired for the VAST event. Attached declarations identify each macro occurrence, registry revision, processing actor, and exact encoding profile.'
        ),
    ]
    macro_declarations: Annotated[
        list[MacroDeclaration] | None,
        Field(
            description='Exact tokens in `url` and their resolver/encoding contracts.', min_length=1
        ),
    ] = None
    offset: Annotated[
        str | None,
        Field(
            description='VAST `offset` attribute. Required when `vast_event` is `progress`; ignored otherwise for compatibility with existing 3.x manifests. Format matches the VAST 4.2 XSD `Tracking@offset` pattern: `HH:MM:SS` or `HH:MM:SS.mmm` for absolute time (two-digit hours, minutes 00–59, seconds 00–59), or an integer percentage 0–100 suffixed with `%`. Negative offsets are NOT permitted — the VAST 4.2 XSD pattern does not allow a leading minus.',
            pattern='^(\\d{2}:[0-5]\\d:[0-5]\\d(\\.\\d{3})?|(100|\\d{1,2})%)$',
        ),
    ] = None
    target: Annotated[
        Target | None,
        Field(
            description='Which VAST creative element this tracker scopes to — `linear` for `<Linear>/<TrackingEvents>`, `non_linear` for `<NonLinearAds>/<TrackingEvents>`, `companion` for `<CompanionAds>/<Companion>/<TrackingEvents>`. Defaults to `linear`. Existing 3.x assets remain structurally permissive; a tracker execution contract applies the standards-valid event/target matrix when matching a creative to a product.'
        ),
    ] = Target.linear
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance.'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['vast_tracker']
var macro_declarations : list[MacroDeclaration] | None
var model_config
var offset : str | None
var provenance : Provenance | None
var target : Target | None
var url : str | MacroBearingUrl3 | MacroBearingUrl4
var vast_event : VastTrackingEvent

Inherited members

class VideoContent (**data: Any)
Expand source code
class VideoAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['video'],
        Field(
            description='Discriminator identifying this as a video asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'video'
    url: Annotated[AnyUrl, Field(description='URL to the video asset')]
    width: Annotated[
        SchemaInt,
        Field(
            description="Width in pixels — the video file's intrinsic native width. Required: a hosted file always has concrete dimensions. (Tag-delivered video carries no width; see the `vast` asset.)",
            ge=1,
        ),
    ]
    height: Annotated[
        SchemaInt,
        Field(
            description="Height in pixels — the video file's intrinsic native height. Required: a hosted file always has concrete dimensions. (Tag-delivered video carries no height; see the `vast` asset.)",
            ge=1,
        ),
    ]
    duration_ms: Annotated[
        SchemaInt | None, Field(description='Video duration in milliseconds', ge=1)
    ] = None
    file_size_bytes: Annotated[SchemaInt | None, Field(description='File size in bytes', ge=1)] = (
        None
    )
    container_format: Annotated[
        str | None, Field(description='Video container format (mp4, webm, mov, etc.)')
    ] = None
    video_codec: Annotated[
        str | None, Field(description='Video codec used (h264, h265, vp9, av1, prores, etc.)')
    ] = None
    video_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Video stream bitrate in kilobits per second', ge=1)
    ] = None
    frame_rate: Annotated[
        str | None,
        Field(
            description="Frame rate as string to preserve precision (e.g., '23.976', '29.97', '30')"
        ),
    ] = None
    frame_rate_type: frame_rate_type_1.FrameRateType | None = None
    scan_type: scan_type_1.ScanType | None = None
    color_space: Annotated[ColorSpace | None, Field(description='Color space of the video')] = None
    hdr_format: Annotated[
        HdrFormat | None,
        Field(description="HDR format if applicable, or 'sdr' for standard dynamic range"),
    ] = None
    chroma_subsampling: Annotated[
        ChromaSubsampling | None, Field(description='Chroma subsampling format')
    ] = None
    video_bit_depth: Annotated[VideoBitDepth | None, Field(description='Video bit depth')] = None
    gop_interval_seconds: Annotated[
        StrictFloat | None, Field(description='GOP/keyframe interval in seconds')
    ] = None
    gop_type: gop_type_1.GopType | None = None
    moov_atom_position: moov_atom_position_1.MoovAtomPosition | None = None
    has_audio: Annotated[
        StrictBool | None, Field(description='Whether the video contains an audio track')
    ] = None
    audio_codec: Annotated[
        str | None,
        Field(description='Audio codec used (aac, aac_lc, he_aac, pcm, mp3, ac3, eac3, etc.)'),
    ] = None
    audio_sampling_rate_hz: Annotated[
        SchemaInt | None, Field(description='Audio sampling rate in Hz (e.g., 44100, 48000)')
    ] = None
    audio_channels: Annotated[
        audio_channel_layout.AudioChannelLayout | None,
        Field(description='Audio channel configuration'),
    ] = None
    audio_bit_depth: Annotated[AudioBitDepth | None, Field(description='Audio bit depth')] = None
    audio_bitrate_kbps: Annotated[
        SchemaInt | None, Field(description='Audio bitrate in kilobits per second', ge=1)
    ] = None
    audio_loudness_lufs: Annotated[
        StrictFloat | None, Field(description='Integrated loudness in LUFS')
    ] = None
    audio_true_peak_dbfs: Annotated[
        StrictFloat | None, Field(description='True peak level in dBFS')
    ] = None
    captions_url: Annotated[
        AnyUrl | None, Field(description='URL to captions file (WebVTT, SRT, etc.)')
    ] = None
    transcript_url: Annotated[
        AnyUrl | None, Field(description='URL to text transcript of the video content')
    ] = None
    audio_description_url: Annotated[
        AnyUrl | None,
        Field(description='URL to audio description track for visually impaired users'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['video']
var audio_bit_depth : AudioBitDepth | None
var audio_bitrate_kbps : int | None
var audio_channels : AudioChannelLayout | None
var audio_codec : str | None
var audio_description_url : pydantic.networks.AnyUrl | None
var audio_loudness_lufs : float | None
var audio_sampling_rate_hz : int | None
var audio_true_peak_dbfs : float | None
var captions_url : pydantic.networks.AnyUrl | None
var chroma_subsampling : ChromaSubsampling | None
var color_space : ColorSpace | None
var container_format : str | None
var duration_ms : int | None
var file_size_bytes : int | None
var frame_rate : str | None
var frame_rate_type : FrameRateType | None
var gop_interval_seconds : float | None
var gop_type : GopType | None
var has_audio : bool | None
var hdr_format : HdrFormat | None
var height : int
var model_config
var moov_atom_position : MoovAtomPosition | None
var provenance : Provenance | None
var scan_type : ScanType | None
var transcript_url : pydantic.networks.AnyUrl | None
var url : pydantic.networks.AnyUrl
var video_bit_depth : VideoBitDepth | None
var video_bitrate_kbps : int | None
var video_codec : str | None
var width : int

Inherited members

class WebhookContent (**data: Any)
Expand source code
class WebhookAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['webhook'],
        Field(
            description='Discriminator identifying this as a webhook asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'webhook'
    url: Annotated[AnyUrl, Field(description='Webhook URL to call for dynamic content')]
    method: Annotated[http_method.HttpMethod | None, Field(description='HTTP method')] = (
        http_method.HttpMethod.POST
    )
    timeout_ms: Annotated[
        SchemaInt | None,
        Field(description='Maximum time to wait for response in milliseconds', ge=10, le=5000),
    ] = 500
    supported_macros: Annotated[
        list[universal_macro.UniversalMacro | str] | None,
        Field(
            description='Universal macros that can be passed to webhook (e.g., DEVICE_TYPE, COUNTRY). See docs/creative/universal-macros.mdx for full list.'
        ),
    ] = None
    required_macros: Annotated[
        list[universal_macro.UniversalMacro | str] | None,
        Field(description='Universal macros that must be provided for webhook to function'),
    ] = None
    response_type: Annotated[
        webhook_response_type.WebhookResponseType,
        Field(description='Expected content type of webhook response'),
    ]
    security: Annotated[Security, Field(description='Security configuration for webhook calls')]
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var asset_type : Literal['webhook']
var method : HttpMethod | None
var model_config
var provenance : Provenance | None
var required_macros : list[UniversalMacro | str] | None
var response_type : WebhookResponseType
var security : Security
var supported_macros : list[UniversalMacro | str] | None
var timeout_ms : int | None
var url : pydantic.networks.AnyUrl

Inherited members

class ZipAsset (**data: Any)
Expand source code
class ZipAsset(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_type: Annotated[
        Literal['zip'],
        Field(
            description='Discriminator identifying this as a zip-bundled asset. See /schemas/creative/asset-types for the registry.'
        ),
    ] = 'zip'
    url: Annotated[AnyUrl, Field(description='URL where the zip archive is hosted. Must be HTTPS.')]
    max_file_size_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum file size in kilobytes. Receivers should reject zips exceeding this.',
            ge=0,
        ),
    ] = None
    entry_point: Annotated[
        str | None,
        Field(
            description="Relative path to the entry file within the zip (typically 'index.html'). Receivers default to 'index.html' if absent."
        ),
    ] = None
    allowed_inner_extensions: Annotated[
        list[str] | None,
        Field(
            description="File extensions permitted inside the zip (e.g., ['html', 'css', 'js', 'png', 'jpg', 'svg', 'webp', 'json', 'woff2']). Receivers may reject zips containing other extensions."
        ),
    ] = None
    backup_image_url: Annotated[
        AnyUrl | None,
        Field(
            description='Fallback image URL for environments that cannot render the bundled creative (e.g., non-HTML5 endpoints, ad blockers). Recommended for HTML5 banners.'
        ),
    ] = None
    digest: Annotated[
        str | None,
        Field(
            description='Optional SHA-256 content digest of the zip archive (sha256:<hex>) for integrity verification. Lets receivers detect tampered or stale archives.',
            pattern='^sha256:[a-f0-9]{64}$',
        ),
    ] = None
    accessibility: Annotated[
        Accessibility | None,
        Field(description='Self-declared accessibility properties for this opaque creative'),
    ] = None
    provenance: Annotated[
        provenance_1.Provenance | None,
        Field(
            description='Provenance metadata for this asset, overrides manifest-level provenance'
        ),
    ] = None

Base model for AdCP types with spec-compliant serialization.

Defaults to extra='ignore' so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.

Important

The env var is resolved once at module import time. Set it in your shell or CI environment before import adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import has no effect on already-imported model classes (they captured the policy at class-body evaluation).

Consumers who want per-model strict validation can override model_config on their subclass.

Create a new model by parsing and validating input data from keyword arguments.

Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var accessibility : Accessibility | None
var allowed_inner_extensions : list[str] | None
var asset_type : Literal['zip']
var backup_image_url : pydantic.networks.AnyUrl | None
var digest : str | None
var entry_point : str | None
var max_file_size_kb : int | None
var model_config
var provenance : Provenance | None
var url : pydantic.networks.AnyUrl

Inherited members