Module adcp.types.domains.formats

Types the AdCP formats schemas declare.

Importing from the domain says which variant you mean, where the flat adcp.types namespace can only bind one class per name:

from adcp.types.domains.formats import <Type>

A type this domain declares in more than one schema is not here: import it from its own schema's module, adcp.types.domains.formats.<schema>. Nothing here is renamed.

Auto-generated from the generated domain tree. DO NOT EDIT MANUALLY. Generation date: 2026-10-04 18:45:11 UTC

Sub-modules

adcp.types.domains.formats.canonical

Classes

class AssetSource5 (*args, **kwds)
Expand source code
class AssetSource5(StrEnum):
    buyer_uploaded = 'buyer_uploaded'
    seller_pre_rendered_from_brief = 'seller_pre_rendered_from_brief'
    seller_human_designed = 'seller_human_designed'
    agent_synthesized = 'agent_synthesized'
    publisher_owned_reference = 'publisher_owned_reference'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var agent_synthesized
var buyer_uploaded
var publisher_owned_reference
var seller_human_designed
var seller_pre_rendered_from_brief
class AudioCodec2 (*args, **kwds)
Expand source code
class AudioCodec2(StrEnum):
    mp3 = 'mp3'
    aac = 'aac'
    wav = 'wav'
    opus = 'opus'
    flac = 'flac'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var aac
var flac
var mp3
var opus
var wav
class CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement (**data: Any)
Expand source code
class CanonicalFormatAgentPlacementAiSurfaceSponsoredPlacement(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description="Marked experimental at 3.1 GA: the canonical's tracking model (mention-level impression + attribution, postback shape, cross-surface dedup) is intentionally underspecified for 3.1. Adopters claiming `agent_placement` ship private tracking integrations; buyer agents MUST treat attribution as adapter-defined until the 3.2 tracking-macro spec lands. Promotion to non-experimental gated on the 3.2 tracking-contract spec."
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — AI-surface sponsored mentions weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Annotated[
        Any | None,
        Field(
            description="agent_placement has minimal buyer-shipped slots — the surface composes the rendered output from brand context (resolved via the manifest's top-level `brand` BrandRef) plus optional offering_ref and landing_page_url assets. None of these assets are rendered verbatim by the buyer; the agent chooses how to use them."
        ),
    ] = [
        {'asset_group_id': 'offering_ref', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    output_modality: Annotated[
        OutputModality | None,
        Field(
            description='How the surface presents the mention. `text` = inline text (chat, search snippet). `audio` = TTS-synthesized voice. `card` = structured card with optional image + text.'
        ),
    ] = None
    max_mention_length_chars: Annotated[
        SchemaInt | None,
        Field(
            description='For text output: maximum length of the surface-composed mention text.',
            ge=1,
        ),
    ] = None
    max_mention_duration_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For audio output: maximum duration of the spoken mention in milliseconds.',
            ge=1,
        ),
    ] = None
    supports_offering_reference: Annotated[
        StrictBool | None,
        Field(
            description='Whether the product accepts an offering reference (specific product/service to promote within the mention) in addition to brand context.'
        ),
    ] = None
    supports_landing_page_url: Annotated[
        StrictBool | None,
        Field(
            description='Whether the surface attaches a landing page URL to the mention (citation, learn-more link).'
        ),
    ] = None
    tone_constraints: Annotated[
        list[str] | None,
        Field(
            description="**Advisory only.** Buyer-declared brand-voice preferences the surface SHOULD honor (e.g., ['formal', 'no_superlatives']). LLM/agentic surfaces have no protocol-level mechanism to verify enforcement — adopters that need hard guarantees should rely on brand.json voice declarations and post-mention review rather than this field. Future revisions may tie this to a structured tone vocabulary; for now treat as free-text guidance."
        ),
    ] = None
    disclosure_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the surface must include an explicit sponsorship disclosure label.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var disclosure_required : bool | None
var experimental : typing.Any | None
var max_mention_duration_ms : int | None
var max_mention_length_chars : int | None
var model_config
var output_modality : OutputModality | None
var slots : typing.Any | None
var supports_landing_page_url : bool | None
var supports_offering_reference : bool | None
var tone_constraints : list[str] | None
var v1_translatable : typing.Any | None

Inherited members

class CanonicalFormatBase (**data: Any)
Expand source code
class CanonicalFormatBase(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        StrictBool | None,
        Field(
            description='When true, this canonical or seller narrowing may not work as declared. Adopters SHOULD preflight it with validate_input or in a sandbox and SHOULD NOT route production budget without testing; experimental status never makes the deprecated v1 path preferable. Drivers include unsettled spec shape, an adopter runtime gap, and custom shapes awaiting promotion. This replaces the earlier status plus runtime_status axes. Sellers SHOULD set experimental whenever a canonical or declaration is not production-ready.'
        ),
    ] = False
    deprecated: Annotated[
        StrictBool | None,
        Field(
            description="When true, this canonical (or a seller's specific narrowing of it) is going away. Existing adopters are supported through the deprecation cycle; new adoption is discouraged. Pair with `migration_target_version` to indicate when the canonical is expected to be removed. Distinct from `experimental`: an experimental canonical may stabilize and stop being experimental; a deprecated canonical is on a sunset path."
        ),
    ] = False
    v1_translatable: Annotated[
        StrictBool | None,
        Field(
            description="Whether this canonical has any v1 named-format equivalent. `true` (default) — the canonical is structurally expressible as one or more v1 named formats (IAB display sizes, VAST tags, DAAST tags, etc.); v1→v2 projection via `v1-canonical-mapping.json` is meaningful. `false` — the canonical is inherently new in v2 and has no v1 form; v1's `list_creative_formats` couldn't express it because the underlying concept (algorithmic surface composition, AI-surface mentions, retail-media catalog placements, multi-card carousels) didn't exist as a v1 named-format archetype.\n\nLets SDKs distinguish two failure modes that today look identical: (a) the registry hasn't covered this canonical yet (correctable — seller adds explicit `canonical` field or files a registry entry) vs (b) no v1 path is possible (informational — buyer needs v2-aware consumption, or seller declares `canonical_formats_only: true` on the product declaration). SDKs encountering `v1_translatable: false` on a canonical SHOULD NOT emit `FORMAT_PROJECTION_FAILED` (which signals registry-coverage gap) — instead surface the inherent v1-unreachability as a different diagnostic or skip silently. The six inherently-v2 canonicals in 3.2 are `image_carousel`, `sponsored_placement`, `responsive_creative`, `agent_placement`, `seller_rendered_stateful_display`, and `coordinated_placements`."
        ),
    ] = True
    since_version: Annotated[
        str | None,
        Field(
            description="AdCP MAJOR.MINOR version that introduced this canonical (e.g., '3.1', '3.2'). Lets adopters reason about minimum protocol version requirements when consuming a format declaration. Patch precision is intentionally rejected — canonicals are introduced at minor-version boundaries.",
            pattern='^[1-9]\\d*\\.(0|[1-9]\\d*)$',
        ),
    ] = None
    migration_target_version: Annotated[
        str | None,
        Field(
            description="AdCP MAJOR.MINOR version by which the working group expects this canonical to stabilize, surface a breaking revision, or (when `deprecated: true`) be removed. Patch precision is intentionally rejected — canonicals shift at minor-version boundaries. Absence signals 'no specific target' (omit the field rather than use a placeholder like 'unknown').",
            pattern='^[1-9]\\d*\\.(0|[1-9]\\d*)$',
        ),
    ] = None
    composition_model: Annotated[
        CompositionModel | None,
        Field(
            description='Whether the surface composes deterministically (buyer can predict per-slot rendering — sponsored_placement, image, video) or algorithmically (surface chooses combinations or phrasing — responsive_creative, agent_placement).'
        ),
    ] = None
    provenance_required: Annotated[
        StrictBool | None,
        Field(
            description='When true, the product rejects unsigned synthesized assets. Builders calling build_creative MUST attach a C2PA-compatible provenance manifest attributing synthesis to the creative agent.'
        ),
    ] = None
    platform_extensions: Annotated[
        list[platform_extension_ref.PlatformExtensionReference] | None,
        Field(
            description='Platform-specific extensions narrowing the canonical (pixel ID shapes, conversion event taxonomies, platform-specific CTAs/destinations). Each extension is a URI+digest reference resolved against the bundled `extensions` map in get_products responses or fetched directly.\n\n**Collision precedence (normative).** When two or more `platform_extensions[]` entries on the same declaration extend the same target (e.g., both extend `tracking`) with overlapping field names, **array order is authoritative — later entries override earlier ones on a per-field basis** (last-in-array-wins). SDKs MUST surface the overlap via the `errors[]` array on the `get_products` response with a structured code (`FORMAT_DECLARATION_DIVERGENT` is appropriate when the overlap appears across dual-emitted shapes; a producer-self-emitted overlap on a single declaration SHOULD use the same code with `error.details: { collision_kind: "platform_extension_field", target, overlapping_fields, winning_extension_uri }`). Producers SHOULD avoid the collision by emitting one extension per target or by partitioning fields across extensions; the deterministic precedence is for last-resort consistency across SDK implementations, not a sanctioned merging strategy.'
        ),
    ] = None
    synthesis_nondeterministic: Annotated[
        StrictBool | None,
        Field(
            description="When true, the format's production pipeline is genuinely nondeterministic — the platform cannot guarantee that synthesis from a given input set produces in-spec output. Veo / Sora / Runway-class generative video, and other AI-synthesis flows where output dimensions, duration, or quality vary per run. Implies a different validation contract: predictive `validate_input` is impossible; the platform's own post-synthesis QA loop applies; if the QA loop exhausts without producing a valid artifact, `build_creative` returns task_failed with a synthesis_failed reason. Distinct from `composition_model` (which describes how the surface composes per-slot rendering, not whether synthesis is deterministic). When false or absent, the format's production is predictable enough that `validate_input` can predict output properties from input properties.\n\n**Compatibility with `asset_source` / `item_production_model`**: `synthesis_nondeterministic: true` MAY pair with any of `seller_pre_rendered_from_brief`, `seller_human_designed`, or `agent_synthesized` (the QA loop is concept-level, not source-specific — 'seller renders from brief but each retry differs' is just as nondeterministic as Veo). It MUST NOT pair with `buyer_uploaded` (the buyer ships pre-rendered bytes; there's no synthesis step to be nondeterministic about). It MUST NOT pair with `publisher_host_recorded` (the publisher's host produces a deterministic-from-script output even if the human voice varies). When `synthesis_nondeterministic: true` is set with an incompatible source, validators SHOULD reject with a structured error."
        ),
    ] = False
    slots: Annotated[
        list[Slot] | None,
        Field(
            description="Programmatic declaration of which canonical asset_group_id slots a manifest targeting this format must (or may) populate. Lets SDK codegen and validators enumerate expected slots without parsing the format's prose description. Each entry references an asset_group_id from the canonical vocabulary registry, paired with an `asset_type` so the validator knows which asset schema to apply. Format-level narrowing parameters that apply across all slots (e.g., flat `headline_max_chars` on responsive_creative) may also live on the format declaration; per-slot constraints (a specific slot's `max_chars` or `max_size_kb`) live on the slot entry."
        ),
    ] = None
    required_connections: Annotated[
        list[downstream_connection_requirement.DownstreamConnectionRequirement] | None,
        Field(
            description='Downstream platform connections or grants required to use this format declaration. These are in addition to the single AdCP caller credential. Use this when a platform product requires multiple downstream grants, such as an advertiser account connection plus a publisher identity or post authorization for published-post references.'
        ),
    ] = None
    reference_mutability: Annotated[
        ReferenceMutability | None,
        Field(
            description='Policy for formats whose `slots` accept a `published_post` reference. `immutable_snapshot`: seller snapshots the referenced post at approval and later source changes do not change the served creative. `mutable_requires_reapproval`: the source post may change and material changes require review before continued serving. `mutable_auto_recheck`: the source post may change and the seller continuously or periodically rechecks authorization/policy without requiring buyer resubmission. Omit when the format has no `published_post` slot.'
        ),
    ] = None
    production_window_business_days: Annotated[
        SchemaInt | None,
        Field(
            description='Typical production turnaround in business days when the format requires seller-side production (e.g., host-recording from a buyer-supplied script). 0 for synchronous (e.g., generative AI); >0 for human-produced (e.g., podcast host-read). Absent when no production is required (buyer uploads complete creative).',
            ge=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

Subclasses

Class variables

var composition_model : adcp.types.domains.formats.canonical._base.CompositionModel | None
var deprecated : bool | None
var experimental : bool | None
var migration_target_version : str | None
var model_config
var platform_extensions : list[PlatformExtensionReference] | None
var production_window_business_days : int | None
var provenance_required : bool | None
var reference_mutability : adcp.types.domains.formats.canonical._base.ReferenceMutability | None
var required_connections : list[DownstreamConnectionRequirement] | None
var since_version : str | None
var slots : list[adcp.types.domains.formats.canonical._base.Slot] | None
var synthesis_nondeterministic : bool | None
var v1_translatable : bool | None

Inherited members

class CanonicalFormatCoordinatedPlacements (**data: Any)
Expand source code
class CanonicalFormatCoordinatedPlacements(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Experimental in AdCP 3.2 while the creative working group gathers implementation evidence for atomic cross-placement composition.'
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description='No v1 named-format equivalent can express a coordinated multi-placement buy.'
        ),
    ] = False
    since_version: Any | None = '3.2'
    composition_model: Any | None = 'deterministic'
    components: Annotated[
        list[
            Components
            | Components1
            | Components2
            | Components3
            | Components4
            | Components5
            | Components6
            | Components7
            | Components8
            | Components9
            | Components10
            | Components11
            | Components12
            | Components13
        ],
        Field(min_length=2),
    ]
    shared_slots: Annotated[
        list[SharedSlot] | None,
        Field(
            description='Manifest slots supplied once and consumed by one or more coordinated components.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var components : list[Components | Components1 | Components2 | Components3 | Components4 | Components5 | Components6 | Components7 | Components8 | Components9 | Components10 | Components11 | Components12 | Components13]
var composition_model : typing.Any | None
var experimental : typing.Any | None
var model_config
var shared_slots : list[SharedSlot] | None
var since_version : typing.Any | None
var v1_translatable : typing.Any | None

Inherited members

class CanonicalFormatDaastAudio (**data: Any)
Expand source code
class CanonicalFormatDaastAudio(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for audio_daast canonical. Buyer ships a DAAST tag (URL or inline XML, 1.0 or 1.1) plus an optional clickthrough URL. Tracking events are inherent to DAAST and don't require explicit slots."
        ),
    ] = [
        {'asset_group_id': 'daast_tag', 'asset_type': 'daast', 'required': True},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    daast_version: Annotated[
        daast_version_1.DaastVersion | None,
        Field(
            deprecated=True,
            description='Deprecated one-element alias for `daast_versions`. Producers use either the singular legacy alias or the plural 3.2 field, never both.',
        ),
    ] = None
    daast_versions: Annotated[
        daast_tracker_constraints.DaastVersions | None,
        Field(
            description="Accepted DAAST versions for this format option. A tracker execution selector's daast_versions must be a nonempty subset of this set."
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRangeItem] | None,
        Field(
            description='[min, max] duration in milliseconds. **Precedence**: `duration_ms_exact` takes precedence when both ship. SDKs SHOULD lint a warning when both fields ship.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    linear_required: StrictBool | None = None
    max_wrapper_depth: Annotated[SchemaInt | None, Field(ge=0)] = None
    ssl_required: StrictBool | None = None
    companion_image_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var companion_image_required : bool | None
var daast_version : DaastVersion | None
var daast_versions : DaastVersions | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRangeItem] | None
var linear_required : bool | None
var max_wrapper_depth : int | None
var model_config
var slots : typing.Any | None
var ssl_required : bool | None

Inherited members

class CanonicalFormatDisplayTag (**data: Any)
Expand source code
class CanonicalFormatDisplayTag(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description='Backward-compatible URL-delivery slots. `tag_url` MUST use `url_type: ad_request`. A format option accepting `inline_markup` or `paired_redirect` overrides this list with a required slot whose `asset_type` is `display_tag`; the display-tag asset keeps paired redirect URLs atomic.'
        ),
    ] = [
        {'asset_group_id': 'tag_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'backup_image', 'asset_type': 'image', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Required tag rendering width in pixels — use for fixed-size slots. For multi-size flexible slots use `sizes[]`; for responsive use `min_width`/`max_width`/`min_height`/`max_height`. Exactly one of `(width, height)`, `sizes[]`, or `min/max_width` + `min/max_height` ranges MUST be set.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Required tag rendering height in pixels. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description="List of accepted (width, height) pairs for a multi-size flexible slot. The buyer's third-party tag must render at one of the listed sizes; the seller picks which size to request at impression time. Mutually exclusive with `(width, height)` and with responsive ranges.",
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted width for responsive third-party tags. Pair with `max_width`. Mutually exclusive with `(width, height)` and `sizes[]`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width for responsive third-party tags. Pair with `min_width`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height for responsive third-party tags. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height for responsive third-party tags. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    supported_tag_types: Annotated[
        list[SupportedTagType] | None,
        Field(
            deprecated=True,
            description='Deprecated ambiguous mechanism list. Use `supported_delivery_types`; markup subtype lives on the `display_tag` asset.',
        ),
    ] = None
    supported_delivery_types: Annotated[
        list[SupportedDeliveryType] | None,
        Field(
            description='Closed set of delivery types this format option can traffic. `paired_redirect` means one atomic ad-request/click-through pair (Internal Redirect semantics), never independently matchable URL slots.',
            min_length=1,
        ),
    ] = None
    ssl_required: Annotated[
        StrictBool | None, Field(description='Whether the tag URL must be HTTPS.')
    ] = None
    max_redirect_depth: Annotated[
        SchemaInt | None, Field(description='Maximum redirect chain depth permitted.', ge=0)
    ] = None
    max_response_time_ms: Annotated[
        SchemaInt | None,
        Field(description='Maximum tag-server response time in milliseconds.', ge=1),
    ] = None
    backup_image_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether a backup image must accompany the tag for environments that cannot render the third-party tag.'
        ),
    ] = None
    backup_image_max_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    om_sdk_required: Annotated[
        StrictBool | None,
        Field(
            description="Whether the buyer's tag must integrate IAB Open Measurement SDK for viewability."
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var backup_image_max_size_kb : int | None
var backup_image_required : bool | None
var height : int | None
var max_height : int | None
var max_redirect_depth : int | None
var max_response_time_ms : int | None
var max_width : int | None
var min_height : int | None
var min_width : int | None
var model_config
var om_sdk_required : bool | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var supported_delivery_types : list[SupportedDeliveryType] | None
var supported_tag_types : list[SupportedTagType] | None
var width : int | None

Inherited members

class CanonicalFormatHostedAudio (**data: Any)
Expand source code
class CanonicalFormatHostedAudio(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for buyer-uploaded audio. Host-read products override with a `script` (asset_type: text) or `creative_brief` (asset_type: brief) slot in place of `audio_main`, plus `asset_source: 'publisher_host_recorded'` and `buyer_asset_acceptance: 'rejected'`. TTS-from-script products override similarly with `asset_source: 'seller_pre_rendered_from_brief'`."
        ),
    ] = [
        {'asset_group_id': 'audio_main', 'asset_type': 'audio', 'required': True},
        {'asset_group_id': 'companion_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'brand_name', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='[min, max] duration in milliseconds. Either endpoint MAY be null to express an unbounded side: [null, 60000] means up to 60s; [15000, null] means at least 15s. [null, null] is invalid because at least one endpoint must be bounded. **Precedence**: when both `duration_ms_exact` and `duration_ms_range` ship on the same product, `duration_ms_exact` takes precedence — buyers MUST validate against the exact value and ignore the range. SDKs SHOULD lint a warning when both fields ship; producers SHOULD pick one.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    audio_codecs: list[AudioCodec] | None = None
    audio_sample_rates: list[AudioSampleRate] | None = None
    audio_channels: list[AudioChannel] | None = None
    min_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_file_size_mb: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum hosted audio file size in decimal megabytes. Agents that proxy or cache media SHOULD advertise their effective transport ceiling here.',
            gt=0.0,
        ),
    ] = None
    loudness_lufs: Annotated[
        StrictFloat | None,
        Field(
            description='Required integrated loudness in LUFS (typical: -16 for streaming/podcast, -23 for broadcast). Negative values.'
        ),
    ] = None
    loudness_tolerance_db: Annotated[
        StrictFloat | None,
        Field(description='Permitted deviation from loudness_lufs in dB.', ge=0.0),
    ] = None
    true_peak_dbfs: Annotated[
        StrictFloat | None, Field(description='Maximum true-peak level in dBFS (typical: -2).')
    ] = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered audio bytes come from. Single shared enum across canonicals (see `image.json#asset_source` for the full semantics). `publisher_host_recorded`: the publisher's host records the audio (podcast host-read pattern); buyer must use the publisher's build_creative capability. `publisher_owned_reference` is valid only when the product accepts a reference asset whose publisher-owned source resolves to playable audio. `publisher_host_recorded` remains the normal audio-specific host-read value."
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description="Whether the product accepts buyer-uploaded audio. When `rejected`, the buyer cannot ship an audio asset directly — they must use build_creative (or sync_creatives with brief inputs) so the seller produces the audio. Combined with `asset_source`, lets a product declare 'I produce audio from briefs and refuse buyer uploads' (asset_source=`seller_pre_rendered_from_brief`, buyer_asset_acceptance=`rejected`)."
        ),
    ] = BuyerAssetAcceptance.accepted
    companion_image_required: StrictBool | None = None
    companion_image_aspect_ratio: str | None = None
    companion_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    brand_name_max_chars: Annotated[SchemaInt | None, Field(ge=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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var asset_source : AssetSource | None
var audio_channels : list[AudioChannel] | None
var audio_codecs : list[AudioCodec] | None
var audio_sample_rates : list[AudioSampleRate] | None
var brand_name_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var companion_image_aspect_ratio : str | None
var companion_image_max_file_size_kb : int | None
var companion_image_required : bool | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var loudness_lufs : float | None
var loudness_tolerance_db : float | None
var max_bitrate_kbps : int | None
var max_file_size_mb : float | None
var min_bitrate_kbps : int | None
var model_config
var slots : typing.Any | None
var true_peak_dbfs : float | None

Inherited members

class CanonicalFormatHostedVideo (**data: Any)
Expand source code
class CanonicalFormatHostedVideo(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description='Default slots for video_hosted canonical. Buyer ships a video asset (file or hosted URL); optional headline, primary text (long-form caption), CTA (typically constrained via `cta_values`), brand_name (typical for vertical short-form), companion_banner (typical for horizontal instream), and clickthrough URL. Products MAY override or extend the default — e.g., remove `companion_banner` for short-form vertical, narrow `cta` to a value enum, mark `landing_page_url` as required.'
        ),
    ] = [
        {'asset_group_id': 'video_main', 'asset_type': 'video', 'required': True},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'brand_name', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'companion_banner', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    orientation: Annotated[
        Orientation | None,
        Field(
            description='Video orientation. Vertical = 9:16 (Reels, Stories, Shorts). Horizontal = 16:9 (instream, CTV). Square = 1:1 (in-feed).'
        ),
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description='Aspect ratio. Inferred from orientation if omitted.',
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    min_width: Annotated[SchemaInt | None, Field(ge=1)] = None
    min_height: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_width: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_height: Annotated[SchemaInt | None, Field(ge=1)] = None
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='[min, max] duration in milliseconds. Either endpoint MAY be null to express an unbounded side: [null, 60000] means up to 60s; [15000, null] means at least 15s. [null, null] is invalid because at least one endpoint must be bounded. **Precedence**: when both `duration_ms_exact` and `duration_ms_range` ship on the same product, `duration_ms_exact` takes precedence — buyers MUST validate against the exact value and ignore the range. SDKs SHOULD lint a warning when both fields ship; producers SHOULD pick one.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship (see `duration_ms_range` description).',
            ge=1,
        ),
    ] = None
    video_codecs: list[VideoCodec] | None = None
    audio_codecs: list[AudioCodec] | None = None
    containers: list[Container] | None = None
    min_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_file_size_mb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size, where 1 MB is exactly 1,000,000 bytes.', ge=1),
    ] = None
    frame_rates: list[StrictFloat] | None = None
    captions: Captions | None = None
    om_sdk_required: StrictBool | None = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    primary_text_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    brand_name_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    cta_values: list[str] | None = None
    companion_banner_widths: Annotated[
        list[CompanionBannerWidth] | None,
        Field(description='Permitted companion banner widths (instream video).'),
    ] = None
    companion_banner_heights: list[CompanionBannerHeight] | None = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description='Where the rendered asset bytes come from. Single shared enum across canonicals. See `image.json#asset_source` for the full semantics. `publisher_host_recorded` is audio-specific and has no defined behavior on video. `publisher_owned_reference` is valid when the product accepts an existing post reference via a `published_post` slot instead of uploaded video bytes. Adopters MUST select a value appropriate to the canonical.'
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description='Whether the product accepts buyer-uploaded video. When `rejected`, the buyer cannot ship a video asset directly — they must use build_creative, sync_creatives with brief inputs, or sync_creatives with an accepted reference asset so the seller produces or resolves the video.'
        ),
    ] = BuyerAssetAcceptance.accepted
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `video_hosted` only `screensaver` is valid (ambient looping video the platform plays on idle). Other experiences route per the matrix in docs/creative/ctv-experiences.mdx; linear CTV video declares no experience.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var aspect_ratio : str | None
var asset_source : AssetSource | None
var audio_codecs : list[AudioCodec] | None
var brand_name_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var captions : Captions | None
var companion_banner_heights : list[CompanionBannerHeight] | None
var companion_banner_widths : list[CompanionBannerWidth] | None
var containers : list[Container] | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var frame_rates : list[float] | None
var headline_max_chars : int | None
var max_bitrate_kbps : int | None
var max_file_size_mb : int | None
var max_height : int | None
var max_width : int | None
var min_bitrate_kbps : int | None
var min_height : int | None
var min_width : int | None
var model_config
var om_sdk_required : bool | None
var orientation : Orientation | None
var primary_text_max_chars : int | None
var slots : typing.Any | None
var video_codecs : list[VideoCodec] | None

Inherited members

class CanonicalFormatHtml5Banner (**data: Any)
Expand source code
class CanonicalFormatHtml5Banner(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for html5 canonical. Buyer ships a zip bundle plus optional backup image (required when `backup_image_required: true`) and clickthrough URL. The zip's entry point is typically `index.html`; click handling uses the `clickTag` (or `clickTAG`) macro substituted by the seller at serve time."
        ),
    ] = [
        {'asset_group_id': 'html5_bundle', 'asset_type': 'zip', 'required': True},
        {'asset_group_id': 'backup_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Required banner width in pixels — use for fixed-size slots. For multi-size flexible slots use `sizes[]`; for responsive use `min_width`/`max_width`/`min_height`/`max_height`. Exactly one of `(width, height)`, `sizes[]`, or `min/max_width` + `min/max_height` ranges MUST be set.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Required banner height in pixels. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description='List of accepted (width, height) pairs for a multi-size flexible slot (publisher banner that accepts 300×250 OR 728×90 OR 970×250). Mirrors OpenRTB `banner.format[]`. Mutually exclusive with `(width, height)` and with responsive ranges.',
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted width for responsive HTML5 banners that adapt within a range. Pair with `max_width`. Mutually exclusive with `(width, height)` and `sizes[]`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width for responsive HTML5 banners. Pair with `min_width`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height for responsive HTML5 banners. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height for responsive HTML5 banners. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    max_initial_load_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum initial-load file size (zip + above-the-fold assets) in kilobytes. IAB display standards: 200 KB for fixed sizes, 100 KB for mobile.',
            ge=1,
        ),
    ] = None
    max_polite_load_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum polite-load file size after host-initiated subload, in kilobytes. IAB display standards: 500 KB for fixed sizes.',
            ge=1,
        ),
    ] = None
    host_initiated_subload: Annotated[
        StrictBool | None,
        Field(
            description='Whether the host page must initiate the polite-load phase. IAB-compliant banners require true.'
        ),
    ] = None
    max_animation_duration_ms: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum total animation duration in milliseconds. IAB standard: 30000 (30 seconds).',
            ge=0,
        ),
    ] = None
    max_cpu_load_percent: Annotated[
        SchemaInt | None,
        Field(description='Maximum CPU load percentage during render.', ge=1, le=100),
    ] = None
    mraid_required: Annotated[
        StrictBool | None,
        Field(description='Whether MRAID compatibility is required (mobile in-app).'),
    ] = None
    mraid_version: Annotated[
        MraidVersion | None,
        Field(description='Required MRAID version when mraid_required is true.'),
    ] = None
    om_sdk_required: Annotated[
        StrictBool | None,
        Field(description='Whether IAB Open Measurement SDK integration is required.'),
    ] = None
    clicktag_macro: Annotated[
        ClicktagMacro | None, Field(description='Name of the click-tag macro the bundle must use.')
    ] = None
    backup_image_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether a backup image must accompany the zip for non-HTML5 environments.'
        ),
    ] = None
    backup_image_max_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum backup image file size in kilobytes.', ge=1)
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var backup_image_max_size_kb : int | None
var backup_image_required : bool | None
var clicktag_macro : ClicktagMacro | None
var height : int | None
var host_initiated_subload : bool | None
var max_animation_duration_ms : int | None
var max_cpu_load_percent : int | None
var max_height : int | None
var max_initial_load_kb : int | None
var max_polite_load_kb : int | None
var max_width : int | None
var min_height : int | None
var min_width : int | None
var model_config
var mraid_required : bool | None
var mraid_version : MraidVersion | None
var om_sdk_required : bool | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var width : int | None

Inherited members

class CanonicalFormatImage (**data: Any)
Expand source code
class CanonicalFormatImage(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    motion_level: MotionLevel | None = None
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for image canonical. Buyer ships an image asset (file or hosted URL) plus optional headline, body text, primary text (long-form caption), CTA (typically constrained to an enum via `cta_values`), and clickthrough URL. Products MAY override the default — make `headline` required, narrow `cta` to a value enum, or remove slots the surface doesn't consume."
        ),
    ] = [
        {'asset_group_id': 'image_main', 'asset_type': 'image', 'required': True},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'body_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description="Logical render width in pixels — use for fixed-size slots (e.g., a 300×250 IAB MREC). When `pixel_ratios` is absent, the required image asset width is the same value (1x). When `pixel_ratios` is present, an accepted asset's intrinsic width is `width × pixel_ratio`. For multi-size flexible slots, use `sizes[]`; for responsive slots, use the min/max fields. The three size modes are mutually exclusive.",
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Logical render height in pixels. Intrinsic asset height is `height × pixel_ratio`, where the ratio defaults to 1 when `pixel_ratios` is absent. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description='List of accepted logical (width, height) render pairs for a multi-size flexible slot. The buyer ships an asset matching one logical size multiplied by one accepted `pixel_ratios` entry (or by 1 when `pixel_ratios` is absent). SDKs MUST treat size and density as separate axes: a 600×500 intrinsic asset at 2x satisfies a logical 300×250 size; it does not create a logical 600×500 placement. Mirrors OpenRTB `banner.format[]` semantics. Mutually exclusive with `(width, height)` and with responsive ranges.',
            min_length=1,
        ),
    ] = None
    pixel_ratios: Annotated[
        list[PixelRatio] | None,
        Field(
            description='Accepted intrinsic-pixel densities for image assets, expressed as intrinsic pixels per logical render pixel (for example `[1, 2]` accepts both standard and Retina renditions). Absence means `[1]` for backward compatibility. This is an acceptance set, not a requirement to submit every rendition: one `image_main` asset satisfying any listed ratio is sufficient unless the effective `image_main` slot declares `required_pixel_ratios`. SDKs determine the effective ratio from `asset.pixel_ratio` when supplied, otherwise infer it from intrinsic asset dimensions divided by the matched logical size. Width and height ratios MUST agree.',
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description="Minimum accepted width in pixels for responsive slots that adapt within a range (e.g., 'any width from 300 to 970'). Use with `max_width` (and optionally `min_height`/`max_height`). Mutually exclusive with `(width, height)` and `sizes[]`.",
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width in pixels for responsive slots. Pair with `min_width`. See `min_width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height in pixels for responsive slots. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height in pixels for responsive slots. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description="Optional aspect ratio constraint (e.g., '1.91:1', '1:1'). When provided alongside `width`/`height`, must agree. When used with `sizes[]` or responsive ranges, narrows accepted entries to those matching the aspect ratio.",
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    max_file_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum file size in kilobytes.', ge=1)
    ] = None
    image_formats: Annotated[
        list[ImageFormat] | None, Field(description='Permitted image file formats.')
    ] = None
    ssl_required: Annotated[
        StrictBool | None,
        Field(description='Whether the image and its trackers must be served over HTTPS.'),
    ] = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    body_text_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    cta_values: Annotated[
        list[str] | None,
        Field(
            description="Permitted CTA values for this product (e.g., ['LEARN_MORE', 'SHOP_NOW'])."
        ),
    ] = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered asset bytes come from. Single shared enum across all canonicals (`image`, `video_hosted`, `audio_hosted` — replaces the earlier per-canonical `image_source` / `video_source` / `audio_source` fields). `buyer_uploaded` (default): buyer ships a pre-rendered asset. `publisher_host_recorded`: publisher's host records the asset (audio-specific; podcast host-read pattern). `seller_pre_rendered_from_brief`: buyer ships a brief plus structured copy; seller renders ONE asset at sync_creatives or build_creative time (generative-DSP pattern). `seller_human_designed`: seller's design team renders manually from a brief. `agent_synthesized`: AI synthesis pipeline; pair with `synthesis_nondeterministic: true` when the platform cannot guarantee in-spec output (Veo/Sora/Imagen-class). `publisher_owned_reference`: buyer references an existing post or publisher-owned object via a `published_post` slot; the seller resolves and serves the referenced content after authorization/review rather than receiving uploaded bytes.\n\nNot every value is meaningful on every canonical — `publisher_host_recorded` is audio-specific; on `image` or `video_hosted` it has no defined behavior. `publisher_owned_reference` is meaningful only when the product's `slots` declaration accepts a reference asset such as `published_post`. Adopters MUST select a value appropriate to the canonical's asset type. The `slots` declaration is the binding contract for what the buyer ships; `asset_source` is informational and lets buyers understand the production model when picking products."
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description="Whether the product accepts buyer-uploaded assets. When `rejected`, the buyer cannot ship pre-rendered bytes directly — they must use build_creative (or sync_creatives with brief inputs or reference assets) so the seller produces or resolves the asset. Combined with `asset_source`, lets a product declare 'I produce assets from briefs and refuse buyer uploads' (asset_source=`seller_pre_rendered_from_brief`, buyer_asset_acceptance=`rejected`) or 'I accept existing post references, not uploaded bytes' (asset_source=`publisher_owned_reference`, buyer_asset_acceptance=`rejected`)."
        ),
    ] = BuyerAssetAcceptance.accepted
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `image` only `pause` and `screensaver` are valid — the image-plus-copy contract the major pause-ad sellers ingest (seller composites the frame; typical canvas 1920×1080 or a transparent-region overlay). Other experiences route per the matrix in docs/creative/ctv-experiences.mdx.'
        ),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers (e.g. `qr_code` on a pause frame). Activations are engagement events, not impressions.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var aspect_ratio : str | None
var asset_source : AssetSource | None
var body_text_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var headline_max_chars : int | None
var height : int | None
var image_formats : list[ImageFormat] | None
var max_file_size_kb : int | 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 motion_level : MotionLevel | None
var pixel_ratios : list[PixelRatio] | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var width : int | None

Inherited members

class CanonicalFormatImageCarousel (**data: Any)
Expand source code
class CanonicalFormatImageCarousel(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — multi-card carousels (Meta carousel, Pinterest pin collections, Snap collection ads) weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for image_carousel. The `cards` slot's value in the manifest is an array of [card-asset](/schemas/core/assets/card-asset.json) objects; `min` / `max` constrain card count."
        ),
    ] = [
        {'asset_group_id': 'cards', 'asset_type': 'card', 'required': True, 'min': 2, 'max': 10},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    card_aspect_ratio: Annotated[
        str | None,
        Field(
            description="Aspect ratio shared across all cards (e.g., '1:1', '1.91:1', '4:5').",
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    min_cards: Annotated[
        SchemaInt | None, Field(description='Minimum card count (typical: 2 or 3).', ge=2)
    ] = None
    max_cards: Annotated[
        SchemaInt | None,
        Field(description='Maximum card count (typical: 6, 10, or 35 depending on platform).'),
    ] = None
    allowed_card_media_asset_types: Annotated[
        list[AllowedCardMediaAssetType] | None,
        Field(
            description='Asset types each card\'s `media` field may carry. Default: [\'image\']. Polymorphic carousels (Meta) allow [\'image\', \'video\']. Renamed from `allowed_card_asset_types` to disambiguate that this constrains the card\'s media payload, not the card-asset itself (which is always asset_type: "card").'
        ),
    ] = None
    allowed_card_asset_types: Annotated[
        list[AllowedCardMediaAssetType] | None,
        Field(
            deprecated=True,
            description='DEPRECATED — alias for `allowed_card_media_asset_types`. Kept for back-compat; prefer the new field name. Removed in 5.0.',
        ),
    ] = None
    card_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    card_video_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    card_video_max_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    primary_text_max_chars: Annotated[
        SchemaInt | None,
        Field(description='Maximum length of the carousel-level primary text.', ge=1),
    ] = None
    card_headline_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Per-card headline character limit. Governs the `headline` field on each card-asset in the `cards` slot.',
            ge=1,
        ),
    ] = None
    card_description_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Per-card description character limit. Governs the `description` field on each card-asset in the `cards` slot. Distinct from `card_headline_max_chars`: description is longer body copy (typically 100-500 chars); headline is the short label (typically 25-40 chars).',
            ge=1,
        ),
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var allowed_card_asset_types : list[AllowedCardMediaAssetType] | None
var allowed_card_media_asset_types : list[AllowedCardMediaAssetType] | None
var card_aspect_ratio : str | None
var card_description_max_chars : int | None
var card_headline_max_chars : int | None
var card_image_max_file_size_kb : int | None
var card_video_max_duration_ms : int | None
var card_video_max_file_size_kb : int | None
var max_cards : int | None
var min_cards : int | None
var model_config
var primary_text_max_chars : int | None
var slots : typing.Any | None
var ssl_required : bool | None
var v1_translatable : typing.Any | None

Inherited members

class CanonicalFormatNativeInFeed (**data: Any)
Expand source code
class CanonicalFormatNativeInFeed(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Stable at 3.1 GA. Shape mirrors IAB OpenRTB Native 1.2 — the renderer contract is well-established across in-feed native and content-recommendation adopters.'
        ),
    ] = False
    v1_translatable: Annotated[
        Any | None,
        Field(
            description='Translates to v1 named native formats (e.g., `native_standard`, `native_content`) via the projection registry. Sellers with existing v1 named native formats SHOULD point `v1_format_ref[]` at them.'
        ),
    ] = True
    slots: Annotated[
        Any | None,
        Field(
            description="Default slot shape for native_in_feed. Mirrors IAB OpenRTB Native 1.2 asset types, including the Native video asset: `video` carries a VAST document (the Native 1.2 `vasttag` field) for video-bearing native units such as CTV menu heroes with focus-triggered playback. Products MAY override (`slots_override` on the projection ref) to narrow per-slot limits (`max_chars` on title/body) or remove unused slots (a content-recommendation slot that doesn't display an icon)."
        ),
    ] = [
        {'asset_group_id': 'title', 'asset_type': 'text', 'required': True},
        {'asset_group_id': 'body_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'main_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'icon', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'advertiser_name', 'asset_type': 'text', 'required': True},
        {'asset_group_id': 'sponsored_label', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'display_url', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'rating', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'price', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'video', 'asset_type': 'vast', 'required': False},
        {'asset_group_id': 'impression_tracker', 'asset_type': 'pixel_tracker', 'required': False},
        {'asset_group_id': 'viewability_tracker', 'asset_type': 'pixel_tracker', 'required': False},
        {'asset_group_id': 'click_tracker', 'asset_type': 'pixel_tracker', 'required': False},
    ]
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On native_in_feed `menu` and `overlay` are valid. `menu`: smart-TV home/menu surfaces where the platform assembles buyer assets (background/main image, logo/icon, copy, optional focus-triggered video); `menu_placement` selects the tile vs headline-banner variant, and catalog-derived sponsored tiles route to `sponsored_placement` instead. `overlay`: seller-composited in-stream overlays supplied as an asset bundle (video, logo, imagery, copy, activation copy) — the contract overlay sellers that do not ingest VAST tags use; VAST-ingesting sellers publish a `video_vast` sibling option instead. The wire name stays `native_in_feed` for 3.x even though neither surface is literally in-feed.'
        ),
    ] = None
    menu_placement: Annotated[
        MenuPlacement | None,
        Field(
            description='Menu surface variant, mapping to OpenRTB Native `plcmttype` 1 (tile/feed) and 3 (headline banner). Valid only with `ctv_ad_experience: "menu"`.'
        ),
    ] = None
    focus_behavior: Annotated[
        FocusBehavior | None,
        Field(
            description='What happens when the viewer\'s remote focus lands on the unit. `autoplay_*` requires a `video` asset; playback method maps to AdCOM playbackmethod on OpenRTB bridges. Valid only with `ctv_ad_experience: "menu"`.'
        ),
    ] = None
    motion_level: Annotated[
        motion_level_1.CreativeMotionLevel | None,
        Field(description='Accepted motion class for the rendered unit (AdCOM attrs 21-23).'),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers (QR, deep link, send-to-device). Activations are engagement events, not impressions.'
        ),
    ] = None
    title_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum character length for the title slot. IAB native typical: 25 (short) to 90 (long). Buyer agents SHOULD validate ship-time title length against this.',
            ge=1,
        ),
    ] = None
    body_text_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum character length for the body_text slot. IAB native typical: 90 (mainline) to 140 (extended).',
            ge=1,
        ),
    ] = None
    cta_max_chars: Annotated[
        SchemaInt | None,
        Field(description='Maximum character length for the cta slot. Typical: 15–25.', ge=1),
    ] = None
    cta_values: Annotated[
        list[str] | None,
        Field(
            description="Permitted CTA values for this product (e.g., ['LEARN_MORE', 'SHOP_NOW', 'SIGN_UP', 'DOWNLOAD']). When set, narrows the cta slot to a closed enum."
        ),
    ] = None
    main_image_sizes: Annotated[
        list[MainImageSize] | None,
        Field(
            description='Accepted logical (width, height) pairs for the main_image slot. Common IAB native sizes: 1200×627 (1.91:1), 1080×1080 (1:1), 1080×1350 (4:5). When the effective main_image slot declares `pixel_ratios`, intrinsic asset dimensions are the matched logical pair multiplied by the selected ratio; absence remains 1x.',
            min_length=1,
        ),
    ] = None
    icon_size: Annotated[
        IconSize | None,
        Field(
            description='Required logical (width, height) for the icon slot when present (typical: 80×80 or 100×100). When the effective icon slot declares `pixel_ratios`, intrinsic dimensions are multiplied by the selected ratio; absence remains 1x.'
        ),
    ] = None
    max_image_file_size_kb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size in kilobytes for main_image and icon.', ge=1),
    ] = None
    image_formats: Annotated[
        list[ImageFormat] | None, Field(description='Permitted image file formats.')
    ] = None
    ssl_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether trackers, landing pages, and image URLs must be served over HTTPS.'
        ),
    ] = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered native assets come from. `publisher_host_recorded` is omitted (audio-specific and not meaningful for native). Other values mirror the shared production-source axis used on `image` / `video_hosted`. `buyer_uploaded` (default): buyer ships pre-rendered title/image/body. `seller_pre_rendered_from_brief`: buyer ships a brief, seller renders the native bundle. `agent_synthesized`: AI synthesis pipeline produces title + image + body from a brief; pair with `synthesis_nondeterministic: true` for generative pipelines that can't guarantee in-spec output. `publisher_owned_reference`: buyer ships an existing published post reference; the seller resolves the post into the native presentation after authorization/review."
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description='Whether the product accepts buyer-uploaded native assets. When `rejected`, the buyer cannot ship pre-rendered title/image/body — they must use `build_creative`, `sync_creatives` with brief inputs, or an accepted `published_post` reference so the seller produces or resolves the native bundle.'
        ),
    ] = BuyerAssetAcceptance.accepted

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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var asset_source : AssetSource | None
var body_text_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var cta_max_chars : int | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var experimental : typing.Any | None
var focus_behavior : FocusBehavior | None
var icon_size : IconSize | None
var image_formats : list[ImageFormat] | None
var main_image_sizes : list[MainImageSize] | None
var max_image_file_size_kb : int | None
var menu_placement : MenuPlacement | None
var model_config
var motion_level : CreativeMotionLevel | None
var slots : typing.Any | None
var ssl_required : bool | None
var title_max_chars : int | None
var v1_translatable : typing.Any | None

Inherited members

class CanonicalFormatResponsiveCreative (**data: Any)
Expand source code
class CanonicalFormatResponsiveCreative(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description="Marked experimental at 3.1 GA: composition is algorithmic (the surface picks combinations and reports per-asset breakdowns), and there's no clean v1-translatable equivalent. Buyers ship asset pools rather than rendered creatives; the surface's per-impression composition cannot be predicted by `validate_input`. Adopters SHOULD validate behavior per surface (Google PMax vs Meta Advantage+ creative differ meaningfully)."
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — algorithmic asset-pool composition (Google PMax / Meta Advantage+ creative) wasn't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Any | None = [
        {
            'asset_group_id': 'headlines',
            'asset_type': 'text',
            'required': True,
            'min': 3,
            'max': 15,
        },
        {
            'asset_group_id': 'long_headlines',
            'asset_type': 'text',
            'required': False,
            'min': 1,
            'max': 5,
        },
        {
            'asset_group_id': 'descriptions',
            'asset_type': 'text',
            'required': True,
            'min': 2,
            'max': 5,
        },
        {
            'asset_group_id': 'images_landscape',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {
            'asset_group_id': 'images_square',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {
            'asset_group_id': 'images_vertical',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {'asset_group_id': 'video', 'asset_type': 'video', 'required': False, 'min': 0, 'max': 5},
        {
            'asset_group_id': 'logo',
            'asset_type': 'image',
            'required': True,
            'min': 1,
            'max': 5,
            'logo_slots': [
                'logo_card_light',
                'logo_card_dark',
                'marketplace_listing',
                'ad_end_card',
            ],
            'required_logo_slots': ['logo_card_light', 'logo_card_dark'],
        },
        {
            'asset_group_id': 'landing_page_url',
            'asset_type': 'url',
            'required': True,
            'min': 1,
            'max': 1,
        },
    ]
    headlines_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    headlines_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    long_headlines_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    long_headlines_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    long_headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    descriptions_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    descriptions_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    description_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    images_landscape_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_landscape_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_landscape_aspect_ratio: str | None = None
    images_square_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_square_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_vertical_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_vertical_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    videos_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    videos_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    video_min_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    video_max_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    logo_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    logo_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    logo_aspect_ratios: list[str] | None = None
    business_name_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    asset_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    supports_catalog_input: Annotated[
        StrictBool | None,
        Field(
            description='Whether the product can additionally consume a catalog reference (e.g., PMax with product feed).'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var asset_image_max_file_size_kb : int | None
var business_name_max_chars : int | None
var description_max_chars : int | None
var descriptions_max : int | None
var descriptions_min : int | None
var experimental : typing.Any | None
var headline_max_chars : int | None
var headlines_max : int | None
var headlines_min : int | None
var images_landscape_aspect_ratio : str | None
var images_landscape_max : int | None
var images_landscape_min : int | None
var images_square_max : int | None
var images_square_min : int | None
var images_vertical_max : int | None
var images_vertical_min : int | None
var logo_aspect_ratios : list[str] | None
var logo_max : int | None
var logo_min : int | None
var long_headline_max_chars : int | None
var long_headlines_max : int | None
var long_headlines_min : int | None
var model_config
var slots : typing.Any | None
var supports_catalog_input : bool | None
var v1_translatable : typing.Any | None
var video_max_duration_ms : int | None
var video_min_duration_ms : int | None
var videos_max : int | None
var videos_min : int | None

Inherited members

class CanonicalFormatSellerRenderedStatefulDisplay (**data: Any)
Expand source code
class CanonicalFormatSellerRenderedStatefulDisplay(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Experimental in AdCP 3.2 while the creative working group gathers implementation evidence across premium web and mobile/app sellers.'
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description='No v1 named-format equivalent can express multiple seller-rendered states and their breakpoint bindings.'
        ),
    ] = False
    since_version: Any | None = '3.2'
    composition_model: Any | None = 'deterministic'
    supply_mode: Annotated[
        SupplyMode | None,
        Field(
            description='Which end of the template contract the buyer feeds. `components`: buyer supplies component slots; seller renders states (no `state_canvases`/`layered_source` assets allowed). `rendered_canvases`: buyer supplies exactly one `state_canvases` image per declared state × breakpoint pair. `layered_source`: buyer ships design source (+ optional `font_files`); seller production derives states (`production_window_business_days` applies) — transitional for sellers without executable templates.'
        ),
    ] = SupplyMode.components
    slots: Annotated[
        Any | None,
        Field(
            description='Default manifest slots; which are consumed depends on `supply_mode`. `state_canvases` images MUST carry `state_id` and `breakpoint_id`, and `state_click_urls` entries MUST carry `state_id` (semantic validators resolve the bindings). Component images SHOULD carry `focal_point` for deterministic seller cropping. `landing_page_url` is the default destination (see `clickthrough`). `font_files` MUST contain only buyer-licensed fonts; publisher-proprietary fonts never travel in manifests. Only image, video, text, url, zip, and pixel_tracker slot asset types are accepted — executable types (javascript, html, css, webhook) are rejected even via `slots` overrides.'
        ),
    ] = [
        {'asset_group_id': 'state_canvases', 'asset_type': 'image', 'required': False, 'min': 1},
        {'asset_group_id': 'logo', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'imagery', 'asset_type': 'image', 'required': False, 'min': 0},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'messaging', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'legal_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'video_main', 'asset_type': 'video', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'state_click_urls', 'asset_type': 'url', 'required': False, 'min': 0},
        {'asset_group_id': 'layered_source', 'asset_type': 'zip', 'required': False},
        {'asset_group_id': 'font_files', 'asset_type': 'zip', 'required': False},
    ]
    states: Annotated[
        list[State],
        Field(
            description='Finite visual states known at buy time; state and breakpoint IDs form the canvas-key matrix. Runtime causes live in `transitions[]`. A single-state unit (topscroll, interscroller, skin) declares one state, no transitions, and typically a `reveal` mechanic.',
            min_length=1,
        ),
    ]
    initial_state_id: Annotated[
        str,
        Field(
            description='State rendered when the unit first becomes visible. MUST resolve to `states[].state_id`; for a single-state unit it MUST equal the sole state.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    reveal: Annotated[
        Reveal | None,
        Field(
            description='How the unit enters view, distinct from state changes. `clip_window`: canvas fixed and progressively exposed through a scrolling window (interscroller, topscroll). `scroll_parallax`: canvas moves at a different rate than content. Reveal is presentation of one canvas, not a transition; do not fabricate a second state to express it.'
        ),
    ] = Reveal.none
    transitions: Annotated[
        list[
            Transitions | Transitions7 | Transitions8 | Transitions9 | Transitions10 | Transitions11
        ]
        | None,
        Field(
            description='Bounded seller-rendered transitions between declared visual states. Required when `states` has more than one entry; MUST be omitted for single-state units. Every non-initial state MUST be reachable from `initial_state_id`. Dismissal is terminal unit behavior declared by `user_controls.dismissible`, not a hidden visual state.',
            min_length=1,
        ),
    ] = None
    clickthrough: Annotated[
        Clickthrough | None,
        Field(
            description='Destination policy. `required` (default): manifest MUST supply `landing_page_url`. `optional`: click-optional units (in-feed brand units) may omit it. `none`: unit is non-clickable; manifests MUST NOT supply `landing_page_url` or `state_click_urls`. Per-state overrides via `state_click_urls` entries carrying `state_id`; `landing_page_url` is the fallback for unlisted states.'
        ),
    ] = Clickthrough.required
    user_controls: Annotated[
        UserControls,
        Field(
            description="When any state anchors as `overlay` or `fullscreen_overlay`, either `dismissible` MUST be true or that state's `close_affordance` MUST be true (dismissibility floor; semantic validators enforce)."
        ),
    ]
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Rectangular areas constraining buyer artwork. Omitted state/breakpoint selectors apply the constraint to every canvas. For fluid or range-sized breakpoints, use percent-unit regions.'
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='Accepted embedded-video duration [min, max]. `duration_ms_exact` takes precedence when both are present.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[SchemaInt | None, Field(ge=1)] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description='Embedded-video aspect ratio.',
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    containers: list[Container] | None = None
    video_playback: VideoPlayback | None = None
    max_initial_load_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_subload_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Ceiling on assets loaded after the window load event (IAB LEAN subload). Pairs with `max_initial_load_kb` to mirror the New Ad Portfolio initial/subload weight pair.',
            ge=1,
        ),
    ] = None
    polite_load: Annotated[
        StrictBool | None,
        Field(
            description="When true, non-initial assets load only after the host page's window load event (IAB LEAN subload boundary)."
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var aspect_ratio : str | None
var canvas_constraints : list[CanvasConstraint] | None
var clickthrough : Clickthrough | None
var composition_model : typing.Any | None
var containers : list[Container] | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var experimental : typing.Any | None
var initial_state_id : str
var max_initial_load_kb : int | None
var max_subload_kb : int | None
var model_config
var polite_load : bool | None
var reveal : Reveal | None
var since_version : typing.Any | None
var slots : typing.Any | None
var states : list[State]
var supply_mode : SupplyMode | None
var transitions : list[Transitions | Transitions7 | Transitions8 | Transitions9 | Transitions10 | Transitions11] | None
var user_controls : UserControls
var v1_translatable : typing.Any | None
var video_playback : VideoPlayback | None

Inherited members

class CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven (**data: Any)
Expand source code
class CanonicalFormatSponsoredPlacementRetailMediaCatalogDriven(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Marked experimental at 3.1 GA: the canonical covers 4 meaningfully different retail-media adapter contracts (Amazon SP, Criteo SP / CitrusAd SP, Pinterest Collection, generative-per-SKU). Adopter contracts vary; buyers MUST validate per-adapter behavior before routing budget. Promotion to non-experimental gated on the #4592 adapter-contract docs work.'
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — retail-media catalog placements weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural, not a registry-coverage gap."
        ),
    ] = False
    slots: Any | None = [
        {'asset_group_id': 'source_catalog', 'required': True, 'asset_type': 'catalog'},
        {'asset_group_id': 'hero_asset', 'required': False, 'asset_type': 'image'},
        {'asset_group_id': 'landing_page_url', 'required': False, 'asset_type': 'url'},
    ]
    supported_catalog_types: Annotated[
        list[catalog_type.CatalogType] | None,
        Field(description='Catalog types this product accepts.'),
    ] = None
    min_items: Annotated[
        SchemaInt | None, Field(description='Minimum catalog item count buyer must supply.', ge=1)
    ] = None
    max_items: Annotated[
        SchemaInt | None, Field(description='Maximum items considered for placement.')
    ] = None
    fanout_mode: Annotated[
        FanoutMode | None,
        Field(
            description='How items map to delivery: per_item = one ad per catalog item; multi_item_in_creative = composed multi-item ad (Pinterest Collection, Snap Collection); single_item = one ad showing one item.'
        ),
    ] = None
    required_catalog_fields: Annotated[
        list[str] | None,
        Field(
            description="Catalog item fields the seller requires (e.g., ['title', 'image_url', 'price'])."
        ),
    ] = None
    supported_id_types: Annotated[
        list[SupportedIdType] | None,
        Field(description='Catalog identifier types the placement renders against.'),
    ] = None
    hero_asset_supported: Annotated[
        StrictBool | None,
        Field(
            description='Whether the buyer can supply a hero/banner asset alongside the catalog (Pinterest Collection pattern).'
        ),
    ] = None
    item_production_model: Annotated[
        ItemProductionModel | None,
        Field(
            description='How each per-item creative is produced. Covers the same production-source axis as `asset_source` on `image` / `video_hosted` / `audio_hosted` but with a 4-value subset — drops `publisher_host_recorded` because it\'s audio-specific and doesn\'t apply to retail-media catalog placements. SDK codegen MAY share a base enum and narrow per-canonical, or emit two distinct enums; either way the wire values overlap exactly for the 4 retained values. `buyer_uploaded` (default, current Amazon/Criteo/CitrusAd pattern): the buyer\'s catalog already contains rendered assets per item; the seller composes the placement using those assets. ("Uploaded" reads slightly off for catalog-keyed items where the buyer didn\'t actively upload bytes — the catalog ingestion already supplied them — but the semantic is the same: rendered bytes are buyer-supplied, not seller-produced.) `seller_pre_rendered_from_brief`: the buyer ships a brief plus the catalog reference; the seller renders one creative per catalog item from the brief at sync_creatives time. `seller_human_designed`: seller\'s design team produces per-item renders manually. `agent_synthesized`: AI synthesis pipeline produces per-item renders; pair with `synthesis_nondeterministic: true` for Veo/Sora-class generative video applied per item. Captures the multi-output generative pattern (1 brief × N catalog items → N rendered creatives) under the existing canonical without requiring a separate canonical. Distinct from `fanout_mode`, which describes how items map to delivery slots after rendering.'
        ),
    ] = ItemProductionModel.buyer_uploaded
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `sponsored_placement`: `menu` (sponsored app/content tiles and rows whose assets derive from a catalog listing — Fire-TV-tile pattern), `squeezeback`, and `in_scene` (seller-composited brand integrations produced from the catalog/brief rather than a buyer wire creative). Asset-bundle menu heroes route to `native_in_feed`.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var ctv_ad_experience : CtvAdExperience | None
var experimental : typing.Any | None
var fanout_mode : FanoutMode | None
var hero_asset_supported : bool | None
var item_production_model : ItemProductionModel | None
var max_items : int | None
var min_items : int | None
var model_config
var required_catalog_fields : list[str] | None
var slots : typing.Any | None
var supported_catalog_types : list[CatalogType] | None
var supported_id_types : list[SupportedIdType] | None
var v1_translatable : typing.Any | None

Inherited members

class CanonicalFormatVastAudio (**data: Any)
Expand source code
class CanonicalFormatVastAudio(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description='Default slots for the audio_vast canonical. The buyer supplies a VAST tag (URL or inline XML) plus an optional clickthrough URL, which falls back to the VAST ClickThrough when omitted. Tracking events and companion creatives carried by the VAST document do not require separate slots.'
        ),
    ] = [
        {'asset_group_id': 'vast_tag', 'asset_type': 'vast', 'required': True},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    vast_versions: Annotated[
        list[vast_version_1.VastVersion] | None,
        Field(
            description='VAST audio versions accepted by this product format option. Standardized audio support begins at VAST 4.1; listing 2.0, 3.0, or 4.0 explicitly declares seller-supported legacy audio interoperability rather than standards-conformant VAST audio. The asset declares exactly one vast_version; compatibility requires membership in this set and the seller-wide execution set.',
            min_length=1,
        ),
    ] = None
    vast_version: Annotated[
        vast_version_1.VastVersion | None,
        Field(
            deprecated=True,
            description='Deprecated one-element alias for vast_versions. Producers use either the singular legacy alias or the plural 3.2 field, never both. VAST 4.1+ is the standards-conformant audio profile; older values declare legacy audio interoperability.',
        ),
    ] = None
    media_file_requirements: Annotated[
        vast_media_file_requirements.VastMediafileRequirements | None,
        Field(
            description='Technical acceptance constraints for alternative audio MediaFile renditions in each resolved InLine linear creative. Declared MIME types must be audio/*; visual-dimension constraints are invalid because VAST represents audio MediaFiles with width and height 0.'
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRangeItem] | None,
        Field(
            description='[min, max] duration in milliseconds. duration_ms_exact takes precedence when both fields are present; SDKs SHOULD warn when both are supplied.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, the resolved audio creative duration must equal this value. Takes precedence over duration_ms_range.',
            ge=1,
        ),
    ] = None
    skippable_after_ms: Annotated[
        SchemaInt | None,
        Field(description='When skippable, the buyer-side skip threshold in milliseconds.', ge=0),
    ] = None
    max_wrapper_depth: Annotated[
        SchemaInt | None, Field(description='Maximum VAST wrapper redirect depth permitted.', ge=0)
    ] = None
    ssl_required: StrictBool | None = None
    companion_image_required: Annotated[
        StrictBool | None,
        Field(description='Whether the resolved VAST audio ad must include a companion creative.'),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var companion_image_required : bool | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRangeItem] | None
var max_wrapper_depth : int | None
var media_file_requirements : VastMediafileRequirements | None
var model_config
var skippable_after_ms : int | None
var slots : typing.Any | None
var ssl_required : bool | None
var vast_version : VastVersion | None
var vast_versions : list[VastVersion] | None

Inherited members

class CanonicalFormatVastVideo (**data: Any)
Expand source code
class CanonicalFormatVastVideo(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for video_vast canonical. Buyer ships a VAST tag (URL or inline XML, VAST 2.x-4.x) plus an optional clickthrough URL (which falls back to the VAST `ClickThrough` element when omitted). Tracking events are inherent to VAST and don't require explicit slots."
        ),
    ] = [
        {'asset_group_id': 'vast_tag', 'asset_type': 'vast', 'required': True},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    orientation: Orientation | None = None
    aspect_ratio: Annotated[
        str | None, Field(pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$')
    ] = None
    vast_versions: Annotated[
        list[vast_version_1.VastVersion] | None,
        Field(
            description='VAST versions accepted by this product format option. The asset still declares exactly one `vast_version`; compatibility requires membership in this set and the seller-wide execution set.',
            min_length=1,
        ),
    ] = None
    vast_version: Annotated[
        vast_version_1.VastVersion | None,
        Field(
            deprecated=True,
            description='Deprecated one-element alias for `vast_versions`. Producers use either the singular legacy alias or the plural 3.2 field, never both.',
        ),
    ] = None
    media_file_requirements: Annotated[
        vast_media_file_requirements.VastMediafileRequirements | None,
        Field(
            description='Technical acceptance constraints for alternative VAST MediaFile renditions. Each applicable resolved InLine linear creative needs at least one MediaFile satisfying all declared constraints.'
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(
            description='Whether VPAID interactivity is supported. When true, the VAST tag may carry VPAID JS/Flash payloads.'
        ),
    ] = None
    vpaid_version: VpaidVersion | None = None
    simid_supported: Annotated[
        StrictBool | None,
        Field(
            description='Whether the seller accepts IAB SIMID through `<InteractiveCreativeFile apiFramework="SIMID">` on a Linear VAST creative. SIMID is not a generic VAST extension and cannot be serialized under NonLinearAds; every `ctv_ad_experience` profile therefore forbids `true`.'
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRangeItem] | None,
        Field(
            description='[min, max] duration in milliseconds. **Precedence**: `duration_ms_exact` takes precedence when both ship. SDKs SHOULD lint a warning when both fields ship.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum placement/player width in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum placement/player width in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum placement/player height in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum placement/player height in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    creative_type: Annotated[
        CreativeType | None,
        Field(
            description='Required VAST creative class: `linear` (in-stream Linear), `nonlinear` (NonLinearAds overlay-class), or `either`. Supersedes `linear_required`; when both are present `creative_type` wins, and validators treat `linear_required: true` with no `creative_type` as `linear`.'
        ),
    ] = None
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option is eligible to serve. On video_vast only `pause`, `screensaver`, `overlay`, `squeezeback`, and `in_scene` are valid (`menu` routes to native_in_feed or sponsored_placement), and `creative_type` MUST be `nonlinear`. Because VAST places `<InteractiveCreativeFile>` only under Linear `<MediaFiles>`, `simid_supported` MUST NOT be true on any of these NonLinear profiles. Per-experience floors: `overlay` and `squeezeback` require a 10s minimum duration; `in_scene` requires a 3s minimum brand-exposure duration and forbids interactivity (`vpaid_enabled` MUST NOT be true); `pause` has no duration floor and ends on viewer or device action.'
        ),
    ] = None
    motion_level: Annotated[
        motion_level_1.CreativeMotionLevel | None,
        Field(description='Accepted motion class for the rendered creative (AdCOM attrs 21-23).'),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers. Activations are engagement events, not impressions.'
        ),
    ] = None
    linear_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the VAST creative must be linear (non-skippable in-stream). Superseded by `creative_type`; retained for pre-3.2 declarations.'
        ),
    ] = None
    skippable_after_ms: Annotated[
        SchemaInt | None,
        Field(
            description='When skippable, the buyer-side skip threshold in milliseconds (e.g., 5000 for 5-second skippable pre-roll).',
            ge=0,
        ),
    ] = None
    max_wrapper_depth: Annotated[
        SchemaInt | None, Field(description='Maximum VAST wrapper redirect depth permitted.', ge=0)
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var aspect_ratio : str | None
var creative_type : CreativeType | None
var ctv_ad_experience : CtvAdExperience | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRangeItem] | None
var linear_required : bool | None
var max_height : int | None
var max_width : int | None
var max_wrapper_depth : int | None
var media_file_requirements : VastMediafileRequirements | None
var min_height : int | None
var min_width : int | None
var model_config
var motion_level : CreativeMotionLevel | None
var orientation : Orientation | None
var simid_supported : bool | None
var skippable_after_ms : int | None
var slots : typing.Any | None
var ssl_required : bool | None
var vast_version : VastVersion | None
var vast_versions : list[VastVersion] | None
var vpaid_enabled : bool | None
var vpaid_version : VpaidVersion | None

Inherited members

class Components (**data: Any)
Expand source code
class Components(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ]
    format_kind: str | None = None
    params: dict[str, Any] | None = 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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : str | None
var format_option_ref : FormatOptionReference1 | FormatOptionReference2
var model_config
var params : dict[str, typing.Any] | None
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components1 (**data: Any)
Expand source code
class Components1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['image'] = 'image'
    params: Annotated[
        Params,
        Field(
            description='Static image creative format. Slots: `image_main` (image asset, file or hosted URL), optional `headline` (text), `body_text` (text), `cta` (text/enum), `landing_page_url` (url). Tracking model: impression pixel + click URL via universal_macros, with optional viewability pixel. Distinct from `html5` (interactive bundles) and `display_tag` (third-party served). AR/dimensions narrow to specific sizes via product parameters — covers IAB display sizes (300x250, 728x90, 970x250, etc.) without a separate iab_size enum.',
            title='Canonical Format: Image',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['image']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components10 (**data: Any)
Expand source code
class Components10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['native_in_feed'] = 'native_in_feed'
    params: Annotated[
        Params10,
        Field(
            description='IAB-shaped native creative for in-feed and content-recommendation surfaces. Default slots cover the primary IAB OpenRTB Native 1.2 asset types — `title` (Title Asset), `body_text` (Data Asset type 2), `main_image` (Image Asset main), `icon` (Image Asset icon), `cta` (Data Asset type 12), `advertiser_name` (Data Asset type 1), `sponsored_label` (Title-adjacent), `landing_page_url` (Link Asset), `display_url` (Data Asset type 11 — visible URL/domain, distinct from clickthrough), `rating` (Data Asset type 3 — app/product rating), `price` (Data Asset type 6 — product price), plus renderer-fired `impression_tracker` / `viewability_tracker` / `click_tracker` (`pixel_tracker`). Products MAY use `slots_override` to add other IAB Native data asset types (likes — type 4, downloads — type 5, saleprice — type 7, phone_number — type 8, address — type 9, desc2 — type 10, etc.) or to remove slots the surface doesn\'t render. The publisher\'s renderer assembles these into its own look-and-feel — feed card, content-recommendation slot, in-stream native unit. Buyer ships a single asset bundle; the surface chooses presentation.\n\n**Scope (normative — buyer-agent routing).** This canonical is the home for:\n- IAB OpenRTB Native 1.2 in-feed native ads (publisher feeds, app feeds)\n- Content-recommendation widgets (Taboola, Outbrain, Yahoo Recommendations)\n- AdMob Native / Yahoo Native publisher slots\n- In-feed sponsored placements without catalog dependency\n\n**Not this canonical:**\n- Catalog-driven retail-media (Amazon SP, Criteo SP, CitrusAd SP) — use `sponsored_placement` (requires `source_catalog`).\n- Algorithmic surface that picks from a buyer-supplied asset pool (Google PMax, Meta Advantage+) — use `responsive_creative`.\n- Multi-card carousel — use `image_carousel`.\n- Video-first native units where the asset is a hosted video file — use `video_hosted` with `applies_to_channels: ["native"]`. (Distinct from the CTV menu profile: a menu hero remains this canonical because the platform assembles the full asset bundle and the video rides the Native 1.2 `vasttag` video asset, playing on focus rather than being the unit itself.)\n\nDistinct from `sponsored_placement` along the catalog axis: native_in_feed is asset-bundle composition; sponsored_placement is catalog-row composition. A buyer agent reading `format_kind: native_in_feed` knows to assemble title + image + body + CTA; reading `format_kind: sponsored_placement` knows to attach a catalog feed.',
            title='Canonical Format: Native In-Feed',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['native_in_feed']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params10
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components11 (**data: Any)
Expand source code
class Components11(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['responsive_creative'] = 'responsive_creative'
    params: Annotated[
        Params11,
        Field(
            description='Buyer supplies a pool of typed assets (multiple headlines, descriptions, images, videos, logos); the surface algorithmically composes combinations per placement. **Composition is algorithmic** — surface picks combinations and reports per-asset performance breakdowns. Covers Google Responsive Display Ads (RDA), Responsive Search Ads (RSA), Performance Max (PMax), Demand Gen, and Meta Advantage+ creative. Industry term: "Responsive" (Google) / "Advantage+ creative" (Meta) / "Dynamic Creative" (older Meta term). Distinct from `sponsored_placement` (catalog-driven, deterministic) and `agent_placement` (AI-surface composition). The structured `slots` field below enumerates expected canonical asset_group_id slots; per-slot count/length narrowing lives in flat parameters (`headlines_min`, `headline_max_chars`, etc.).',
            title='Canonical Format: Responsive Creative',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['responsive_creative']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params11
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components12 (**data: Any)
Expand source code
class Components12(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['agent_placement'] = 'agent_placement'
    params: Annotated[
        Params12,
        Field(
            description="**3.2-track canonical.** The structural shape (algorithmic composition + brand-context input + optional offering/landing_page) is captured here so adopters can declare against it in 3.1 catalogs, but the **mention-level tracking contract is intentionally underspecified for 3.1**: no normative macro vocabulary, no postback shape, no cross-surface dedup model. Adopters claiming `agent_placement` in 3.1 ship private tracking integrations and SHOULD leave `experimental: true` on the product declaration that references this canonical; buyer agents MUST treat agent_placement attribution as adapter-defined until the 3.2 tracking-macro spec lands. The canonical promotes to a normatively-buyer-callable surface in 3.2 (or later) once the tracking contract is specified.\n\nSponsored placement integrated into an AI-surface's response to a user. Buyer supplies a `BrandRef` (resolving brand.json for context), an optional `offering_ref` to focus the mention on a specific offering, and an optional `landing_page_url` the surface MAY attach as a citation. The surface (LLM, voice assistant, sponsored-search ranker) composes a natural-language mention, sponsored card, or audio snippet within its response to a user query. **Composition is algorithmic** — the agent chooses phrasing and presentation. Output asset_type varies by surface: `text` for chat UIs and sponsored search snippets; `audio` (synthesized) for voice assistants; `card` for structured AI-surface result cards. Tracking model: mention-level impression + attribution events; per-mention id keys back to brand and offering — but see the 3.2-track note above; the wire shape of these events is not yet specified. Distinct from `si_chat` (which is the user-converses-with-brand's-agent pattern — brand owns the conversational surface) and from `sponsored_placement` (retail-media catalog-driven). Parallels `sponsored_placement` structurally: both are surface-composed placements; agent_placement is for AI/agentic surfaces, sponsored_placement is for retail media.",
            title='Canonical Format: Agent Placement (AI-surface sponsored placement)',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['agent_placement']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params12
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components13 (**data: Any)
Expand source code
class Components13(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['seller_rendered_stateful_display'] = 'seller_rendered_stateful_display'
    params: Annotated[
        Params13,
        Field(
            description='Seller-rendered display unit whose declaration is an executable template contract: buyer-known visual states, explicit transitions, breakpoint canvases, and per-state slot bindings. The seller owns the runtime; `supply_mode` declares which end the buyer feeds. For machine-rendered `components` and `rendered_canvases` supply, sellers MUST support `preview_creative` returning every state × breakpoint from a candidate manifest. `layered_source` instead follows the asynchronous seller-production preview path after the declared production window. `composition_model: deterministic` describes serving the finished states, not instant derivation from layered source. Buyer-executable HTML/MRAID is `html5`, a buyer-delivered tag is `display_tag`, arbitrary games/hotspots/scripts remain `custom`, and per-impression algorithmic assembly is `responsive_creative`.',
            title='Canonical Format: Seller-Rendered Stateful Display',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['seller_rendered_stateful_display']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params13
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components2 (**data: Any)
Expand source code
class Components2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['html5'] = 'html5'
    params: Annotated[
        Params2,
        Field(
            description="Interactive HTML5 banner delivered as a zip archive. Slot: `html5_bundle` (zip asset). Tracking model: MRAID + IAB Open Measurement (OM-SDK) + click-tag macro substitution + backup image fallback. Receivers unpack the zip, validate internal structure, and serve from CDN. Distinct from `image` (static, non-interactive) and `display_tag` (third-party served). The zip's entry point is typically `index.html`; click handling uses `clickTag` (or `clickTAG`) macro substitution.",
            title='Canonical Format: HTML5 Banner',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['html5']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params2
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components3 (**data: Any)
Expand source code
class Components3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['display_tag'] = 'display_tag'
    params: Annotated[
        Params3,
        Field(
            description='Third-party-served display creative delivered as one of three explicit representations: a single ad-request URL, byte-preserved inline markup, or an atomic paired redirect (`ad_request_url` plus `clickthrough_url`). The backward-compatible default slot remains `tag_url` (`url_type: ad_request`). Format options accepting inline or paired delivery override `slots` with a `display_tag` asset and declare `supported_delivery_types`. Tracking is opaque to the seller except for declared macro resolution. Distinct from `image` and seller-hosted `html5` zip bundles.',
            title='Canonical Format: Display Tag',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['display_tag']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params3
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components4 (**data: Any)
Expand source code
class Components4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['image_carousel'] = 'image_carousel'
    params: Annotated[
        Params4,
        Field(
            description='Multi-card swipeable carousel. The buyer ships a `cards` slot whose value is an **array** of [card-asset](/schemas/core/assets/card-asset.json) objects (a single key with an array value — NOT one key per card, NOT dotted/bracketed paths). Each card-asset carries: `asset_type: "card"`, `media` (an image or video asset), optional `headline` (text), optional `landing_page_url` (url asset). Per-card structure is the same across all cards; mixed orientations not allowed within a single carousel. Tracking model: per-card impression and engagement pixels + carousel-level engagement (swipe, view-time). Allowed asset types for a card\'s `media` field: `image` and `video` (Meta-style mixed-media); platforms can narrow to image-only or video-only via `allowed_card_media_asset_types`.\n\nThe manifest\'s `assets.cards` value is an array of card-asset objects. Example: `"cards": [{"asset_type": "card", "media": {"asset_type": "image", "url": "..."}, "headline": "Buy now", "landing_page_url": {"asset_type": "url", "url_type": "clickthrough", "url": "..."}}, ...]`. Each card-asset validates against the card schema; per-card platform extensions attach via the card\'s `platform_extensions` field, never via inline non-canonical keys.',
            title='Canonical Format: Image Carousel',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['image_carousel']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params4
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components5 (**data: Any)
Expand source code
class Components5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['video_hosted'] = 'video_hosted'
    params: Annotated[
        Params5,
        Field(
            description='Direct video file (mp4/webm/mov) hosted by the buyer. Slot: `video_main` (video asset, file or hosted URL), optional `headline`, `brand_name`, `cta`, `companion_banner`, `landing_page_url`. Tracking model: IAB Open Measurement SDK + external impression/click/quartile pixels via universal_macros. Orientation is a parameter (vertical 9:16 / horizontal 16:9 / square 1:1); slot shape includes optional `brand_name` (typical for vertical short-form) and optional `companion_banner` (typical for horizontal instream). Distinct from `video_vast` (VAST tag, inherent VAST event tracking) — receivers fire impression and click pixels at delivery time.',
            title='Canonical Format: Hosted Video',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['video_hosted']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params5
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components6 (**data: Any)
Expand source code
class Components6(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['video_vast'] = 'video_vast'
    params: Annotated[
        Params6,
        Field(
            description='VAST-tag-delivered video creative. Slot: `vast_tag` (vast asset, URL or inline XML, VAST 2.x-4.x). Tracking model: VAST events inherent to the spec — `impression`, `firstQuartile`, `midpoint`, `thirdQuartile`, `complete`, `start`, `pause`, `resume`, `mute`, `unmute`, `expand`, `collapse`, `fullscreen`, `creativeView`, `clickTracking`, `error`. VPAID interactivity via `vpaid_enabled: true` flag. SIMID is carried by the first-class VAST 4.1+ `<InteractiveCreativeFile apiFramework="SIMID">` element on Linear creatives. Orientation is a parameter (vertical / horizontal / square). Distinct from `video_hosted` (direct file with external tracking).',
            title='Canonical Format: VAST Video',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['video_vast']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params6
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components7 (**data: Any)
Expand source code
class Components7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['audio_hosted'] = 'audio_hosted'
    params: Annotated[
        Params7,
        Field(
            description="Direct audio creative — buyer ships an `audio` asset (mp3/aac/wav) for asset-driven products, or ships a `script` / `creative_brief` text asset for products where the seller produces audio internally (podcast host-reads, TTS synthesis). Optional companion slots: `companion_image`, `brand_name`, `landing_page_url`. Tracking model: standard impression + completion + companion-image-click pixels via universal_macros. Distinct from `audio_daast` (DAAST tag, inherent DAAST event tracking). For host-reads and synthesized audio, the format declares `asset_source: 'publisher_host_recorded'` or `'agent_synthesized'` plus `buyer_asset_acceptance: 'rejected'`; the format's `slots` declaration enumerates which assets the buyer ships (e.g., `script` text asset for host-reads). The seller decides how to consume each asset (render verbatim vs produce audio from text) — there is no separate manifest 'inputs' map; everything the buyer ships goes in `assets`.",
            title='Canonical Format: Hosted Audio',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['audio_hosted']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params7
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components8 (**data: Any)
Expand source code
class Components8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['audio_daast'] = 'audio_daast'
    params: Annotated[
        Params8,
        Field(
            description='DAAST-tag-delivered audio creative (audio analog of VAST). Slot: `daast_tag` (daast asset, URL or inline XML). Tracking model: DAAST events inherent to the spec — `impression`, `firstQuartile`, `midpoint`, `thirdQuartile`, `complete`, `start`, `pause`, `resume`, `mute`, `unmute`, `clickTracking`, `error`. Distinct from `audio_hosted` (direct file with external tracking).',
            title='Canonical Format: DAAST Audio',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['audio_daast']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params8
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class Components9 (**data: Any)
Expand source code
class Components9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    component_id: Annotated[
        str,
        Field(
            description='Stable coordination-local component identifier. Values MUST be unique within `components[]`.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    placement_ref: Annotated[
        placement_ref_1.PlacementReference,
        Field(
            description="Public product placement this component supplies. MUST resolve against the containing product's `placements[]`."
        ),
    ]
    required: StrictBool
    sequence: Annotated[
        SchemaInt | None,
        Field(
            description='Declared presentation order for sequential-messaging coordinated buys. Components sharing a sequence value present simultaneously; absent means unordered/simultaneous (default). Sequence declares seller-rendered ordering, not buyer-controlled timing.',
            ge=1,
        ),
    ] = None
    serving_policy: Annotated[
        ServingPolicy | None,
        Field(
            description='Per-component serving/tracking policy. Some sellers restrict specific components (e.g., page skins) to first-party serving while allowing third-party tags on sibling components. Defaults to the product-level policy when absent.'
        ),
    ] = None
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Artwork constraints applied to this component, including safe areas and seller-reserved regions.'
        ),
    ] = None
    format_option_ref: Annotated[
        format_option_ref_1.FormatOptionReference | None,
        Field(
            description='Reference to a sibling `format_options[]` entry on the same product. It MUST NOT resolve to `custom` or `coordinated_placements`.'
        ),
    ] = None
    format_kind: Literal['sponsored_placement'] = 'sponsored_placement'
    params: Annotated[
        Params9,
        Field(
            description="Catalog-driven retail-media format. Slot: `source_catalog` (catalog asset — product/SKU/ASIN/GTIN catalog reference, REQUIRED), optional `hero_asset`, optional `landing_page_url`. Buyer supplies the catalog reference; surface composes per-item or multi-item rendering using its native placement template. **Composition is deterministic** — buyer can predict per-slot rendering from the catalog item structure. Tracking model: per-item impression + click + conversion (catalog-keyed via offering_id/sku/gtin macros). Covers Amazon Sponsored Products, Criteo Sponsored Products, CitrusAd Sponsored Products, Walmart Connect Sponsored Products, Pinterest Collection (catalog-driven mode).\n\n**Scope (normative — buyer-agent routing).** This canonical is the home for catalog-driven retail-media placements ONLY. The defining feature is the `source_catalog` slot — products under this canonical compose their creative *per catalog item* using the buyer-supplied catalog feed. Without a catalog feed there is nothing to render against. Buyer agents reading `format_kind: sponsored_placement` MUST attach a catalog reference; sellers MUST require `source_catalog` in the manifest.\n\n**Not this canonical (route elsewhere):**\n- IAB in-feed native ads, content-recommendation widgets (Taboola, Outbrain, Yahoo Native, AdMob Native, in-feed sponsored cards) — use `native_in_feed` (asset-bundle composition; no catalog).\n- Algorithmic surface that picks from a buyer-supplied asset pool (Google PMax, Meta Advantage+) — use `responsive_creative`.\n- Single-image or single-video creative — use `image` or `video_hosted`.\n\nThe earlier broader framing ('any sponsored placement') was too loose for buyer-agent routing — a buyer reading `sponsored_placement` couldn't disambiguate a catalog-driven Amazon SP from an in-feed Taboola widget. As of 3.1, the canonical is narrowed to catalog-keyed retail-media; native moves to `native_in_feed`. Distinct from `responsive_creative` (algorithmic combinator from buyer pool) and `agent_placement` (text/audio AI-surface composition).",
            title='Canonical Format: Sponsored Placement (retail-media catalog-driven)',
        ),
    ]

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_constraints : list[CanvasConstraint] | None
var component_id : str
var format_kind : Literal['sponsored_placement']
var format_option_ref : FormatOptionReference1 | FormatOptionReference2 | None
var model_config
var params : Params9
var placement_ref : PlacementReference
var required : bool
var sequence : int | None
var serving_policy : ServingPolicy | None

Inherited members

class CompositionModel (*args, **kwds)
Expand source code
class CompositionModel(StrEnum):
    deterministic = 'deterministic'
    algorithmic = 'algorithmic'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var algorithmic
var deterministic
class ImageFormat1 (*args, **kwds)
Expand source code
class ImageFormat1(StrEnum):
    jpg = 'jpg'
    jpeg = 'jpeg'
    png = 'png'
    gif = 'gif'
    webp = 'webp'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var gif
var jpeg
var jpg
var png
var webp
class Params (**data: Any)
Expand source code
class Params(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    motion_level: MotionLevel | None = None
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for image canonical. Buyer ships an image asset (file or hosted URL) plus optional headline, body text, primary text (long-form caption), CTA (typically constrained to an enum via `cta_values`), and clickthrough URL. Products MAY override the default — make `headline` required, narrow `cta` to a value enum, or remove slots the surface doesn't consume."
        ),
    ] = [
        {'asset_group_id': 'image_main', 'asset_type': 'image', 'required': True},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'body_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description="Logical render width in pixels — use for fixed-size slots (e.g., a 300×250 IAB MREC). When `pixel_ratios` is absent, the required image asset width is the same value (1x). When `pixel_ratios` is present, an accepted asset's intrinsic width is `width × pixel_ratio`. For multi-size flexible slots, use `sizes[]`; for responsive slots, use the min/max fields. The three size modes are mutually exclusive.",
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Logical render height in pixels. Intrinsic asset height is `height × pixel_ratio`, where the ratio defaults to 1 when `pixel_ratios` is absent. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description='List of accepted logical (width, height) render pairs for a multi-size flexible slot. The buyer ships an asset matching one logical size multiplied by one accepted `pixel_ratios` entry (or by 1 when `pixel_ratios` is absent). SDKs MUST treat size and density as separate axes: a 600×500 intrinsic asset at 2x satisfies a logical 300×250 size; it does not create a logical 600×500 placement. Mirrors OpenRTB `banner.format[]` semantics. Mutually exclusive with `(width, height)` and with responsive ranges.',
            min_length=1,
        ),
    ] = None
    pixel_ratios: Annotated[
        list[PixelRatio] | None,
        Field(
            description='Accepted intrinsic-pixel densities for image assets, expressed as intrinsic pixels per logical render pixel (for example `[1, 2]` accepts both standard and Retina renditions). Absence means `[1]` for backward compatibility. This is an acceptance set, not a requirement to submit every rendition: one `image_main` asset satisfying any listed ratio is sufficient unless the effective `image_main` slot declares `required_pixel_ratios`. SDKs determine the effective ratio from `asset.pixel_ratio` when supplied, otherwise infer it from intrinsic asset dimensions divided by the matched logical size. Width and height ratios MUST agree.',
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description="Minimum accepted width in pixels for responsive slots that adapt within a range (e.g., 'any width from 300 to 970'). Use with `max_width` (and optionally `min_height`/`max_height`). Mutually exclusive with `(width, height)` and `sizes[]`.",
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width in pixels for responsive slots. Pair with `min_width`. See `min_width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height in pixels for responsive slots. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height in pixels for responsive slots. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description="Optional aspect ratio constraint (e.g., '1.91:1', '1:1'). When provided alongside `width`/`height`, must agree. When used with `sizes[]` or responsive ranges, narrows accepted entries to those matching the aspect ratio.",
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    max_file_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum file size in kilobytes.', ge=1)
    ] = None
    image_formats: Annotated[
        list[ImageFormat] | None, Field(description='Permitted image file formats.')
    ] = None
    ssl_required: Annotated[
        StrictBool | None,
        Field(description='Whether the image and its trackers must be served over HTTPS.'),
    ] = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    body_text_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    cta_values: Annotated[
        list[str] | None,
        Field(
            description="Permitted CTA values for this product (e.g., ['LEARN_MORE', 'SHOP_NOW'])."
        ),
    ] = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered asset bytes come from. Single shared enum across all canonicals (`image`, `video_hosted`, `audio_hosted` — replaces the earlier per-canonical `image_source` / `video_source` / `audio_source` fields). `buyer_uploaded` (default): buyer ships a pre-rendered asset. `publisher_host_recorded`: publisher's host records the asset (audio-specific; podcast host-read pattern). `seller_pre_rendered_from_brief`: buyer ships a brief plus structured copy; seller renders ONE asset at sync_creatives or build_creative time (generative-DSP pattern). `seller_human_designed`: seller's design team renders manually from a brief. `agent_synthesized`: AI synthesis pipeline; pair with `synthesis_nondeterministic: true` when the platform cannot guarantee in-spec output (Veo/Sora/Imagen-class). `publisher_owned_reference`: buyer references an existing post or publisher-owned object via a `published_post` slot; the seller resolves and serves the referenced content after authorization/review rather than receiving uploaded bytes.\n\nNot every value is meaningful on every canonical — `publisher_host_recorded` is audio-specific; on `image` or `video_hosted` it has no defined behavior. `publisher_owned_reference` is meaningful only when the product's `slots` declaration accepts a reference asset such as `published_post`. Adopters MUST select a value appropriate to the canonical's asset type. The `slots` declaration is the binding contract for what the buyer ships; `asset_source` is informational and lets buyers understand the production model when picking products."
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description="Whether the product accepts buyer-uploaded assets. When `rejected`, the buyer cannot ship pre-rendered bytes directly — they must use build_creative (or sync_creatives with brief inputs or reference assets) so the seller produces or resolves the asset. Combined with `asset_source`, lets a product declare 'I produce assets from briefs and refuse buyer uploads' (asset_source=`seller_pre_rendered_from_brief`, buyer_asset_acceptance=`rejected`) or 'I accept existing post references, not uploaded bytes' (asset_source=`publisher_owned_reference`, buyer_asset_acceptance=`rejected`)."
        ),
    ] = BuyerAssetAcceptance.accepted
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `image` only `pause` and `screensaver` are valid — the image-plus-copy contract the major pause-ad sellers ingest (seller composites the frame; typical canvas 1920×1080 or a transparent-region overlay). Other experiences route per the matrix in docs/creative/ctv-experiences.mdx.'
        ),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers (e.g. `qr_code` on a pause frame). Activations are engagement events, not impressions.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var aspect_ratio : str | None
var asset_source : AssetSource | None
var body_text_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var headline_max_chars : int | None
var height : int | None
var image_formats : list[ImageFormat] | None
var max_file_size_kb : int | 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 motion_level : MotionLevel | None
var pixel_ratios : list[PixelRatio] | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var width : int | None

Inherited members

class Params10 (**data: Any)
Expand source code
class Params10(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Stable at 3.1 GA. Shape mirrors IAB OpenRTB Native 1.2 — the renderer contract is well-established across in-feed native and content-recommendation adopters.'
        ),
    ] = False
    v1_translatable: Annotated[
        Any | None,
        Field(
            description='Translates to v1 named native formats (e.g., `native_standard`, `native_content`) via the projection registry. Sellers with existing v1 named native formats SHOULD point `v1_format_ref[]` at them.'
        ),
    ] = True
    slots: Annotated[
        Any | None,
        Field(
            description="Default slot shape for native_in_feed. Mirrors IAB OpenRTB Native 1.2 asset types, including the Native video asset: `video` carries a VAST document (the Native 1.2 `vasttag` field) for video-bearing native units such as CTV menu heroes with focus-triggered playback. Products MAY override (`slots_override` on the projection ref) to narrow per-slot limits (`max_chars` on title/body) or remove unused slots (a content-recommendation slot that doesn't display an icon)."
        ),
    ] = [
        {'asset_group_id': 'title', 'asset_type': 'text', 'required': True},
        {'asset_group_id': 'body_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'main_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'icon', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'advertiser_name', 'asset_type': 'text', 'required': True},
        {'asset_group_id': 'sponsored_label', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'display_url', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'rating', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'price', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'video', 'asset_type': 'vast', 'required': False},
        {'asset_group_id': 'impression_tracker', 'asset_type': 'pixel_tracker', 'required': False},
        {'asset_group_id': 'viewability_tracker', 'asset_type': 'pixel_tracker', 'required': False},
        {'asset_group_id': 'click_tracker', 'asset_type': 'pixel_tracker', 'required': False},
    ]
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On native_in_feed `menu` and `overlay` are valid. `menu`: smart-TV home/menu surfaces where the platform assembles buyer assets (background/main image, logo/icon, copy, optional focus-triggered video); `menu_placement` selects the tile vs headline-banner variant, and catalog-derived sponsored tiles route to `sponsored_placement` instead. `overlay`: seller-composited in-stream overlays supplied as an asset bundle (video, logo, imagery, copy, activation copy) — the contract overlay sellers that do not ingest VAST tags use; VAST-ingesting sellers publish a `video_vast` sibling option instead. The wire name stays `native_in_feed` for 3.x even though neither surface is literally in-feed.'
        ),
    ] = None
    menu_placement: Annotated[
        MenuPlacement | None,
        Field(
            description='Menu surface variant, mapping to OpenRTB Native `plcmttype` 1 (tile/feed) and 3 (headline banner). Valid only with `ctv_ad_experience: "menu"`.'
        ),
    ] = None
    focus_behavior: Annotated[
        FocusBehavior | None,
        Field(
            description='What happens when the viewer\'s remote focus lands on the unit. `autoplay_*` requires a `video` asset; playback method maps to AdCOM playbackmethod on OpenRTB bridges. Valid only with `ctv_ad_experience: "menu"`.'
        ),
    ] = None
    motion_level: Annotated[
        motion_level_1.CreativeMotionLevel | None,
        Field(description='Accepted motion class for the rendered unit (AdCOM attrs 21-23).'),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers (QR, deep link, send-to-device). Activations are engagement events, not impressions.'
        ),
    ] = None
    title_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum character length for the title slot. IAB native typical: 25 (short) to 90 (long). Buyer agents SHOULD validate ship-time title length against this.',
            ge=1,
        ),
    ] = None
    body_text_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum character length for the body_text slot. IAB native typical: 90 (mainline) to 140 (extended).',
            ge=1,
        ),
    ] = None
    cta_max_chars: Annotated[
        SchemaInt | None,
        Field(description='Maximum character length for the cta slot. Typical: 15–25.', ge=1),
    ] = None
    cta_values: Annotated[
        list[str] | None,
        Field(
            description="Permitted CTA values for this product (e.g., ['LEARN_MORE', 'SHOP_NOW', 'SIGN_UP', 'DOWNLOAD']). When set, narrows the cta slot to a closed enum."
        ),
    ] = None
    main_image_sizes: Annotated[
        list[MainImageSize] | None,
        Field(
            description='Accepted logical (width, height) pairs for the main_image slot. Common IAB native sizes: 1200×627 (1.91:1), 1080×1080 (1:1), 1080×1350 (4:5). When the effective main_image slot declares `pixel_ratios`, intrinsic asset dimensions are the matched logical pair multiplied by the selected ratio; absence remains 1x.',
            min_length=1,
        ),
    ] = None
    icon_size: Annotated[
        IconSize | None,
        Field(
            description='Required logical (width, height) for the icon slot when present (typical: 80×80 or 100×100). When the effective icon slot declares `pixel_ratios`, intrinsic dimensions are multiplied by the selected ratio; absence remains 1x.'
        ),
    ] = None
    max_image_file_size_kb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size in kilobytes for main_image and icon.', ge=1),
    ] = None
    image_formats: Annotated[
        list[ImageFormat1] | None, Field(description='Permitted image file formats.')
    ] = None
    ssl_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether trackers, landing pages, and image URLs must be served over HTTPS.'
        ),
    ] = None
    asset_source: Annotated[
        AssetSource5 | None,
        Field(
            description="Where the rendered native assets come from. `publisher_host_recorded` is omitted (audio-specific and not meaningful for native). Other values mirror the shared production-source axis used on `image` / `video_hosted`. `buyer_uploaded` (default): buyer ships pre-rendered title/image/body. `seller_pre_rendered_from_brief`: buyer ships a brief, seller renders the native bundle. `agent_synthesized`: AI synthesis pipeline produces title + image + body from a brief; pair with `synthesis_nondeterministic: true` for generative pipelines that can't guarantee in-spec output. `publisher_owned_reference`: buyer ships an existing published post reference; the seller resolves the post into the native presentation after authorization/review."
        ),
    ] = AssetSource5.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description='Whether the product accepts buyer-uploaded native assets. When `rejected`, the buyer cannot ship pre-rendered title/image/body — they must use `build_creative`, `sync_creatives` with brief inputs, or an accepted `published_post` reference so the seller produces or resolves the native bundle.'
        ),
    ] = BuyerAssetAcceptance.accepted

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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var asset_source : AssetSource5 | None
var body_text_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var cta_max_chars : int | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var experimental : typing.Any | None
var focus_behavior : FocusBehavior | None
var icon_size : IconSize | None
var image_formats : list[ImageFormat1] | None
var main_image_sizes : list[MainImageSize] | None
var max_image_file_size_kb : int | None
var menu_placement : MenuPlacement | None
var model_config
var motion_level : CreativeMotionLevel | None
var slots : typing.Any | None
var ssl_required : bool | None
var title_max_chars : int | None
var v1_translatable : typing.Any | None

Inherited members

class Params11 (**data: Any)
Expand source code
class Params11(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description="Marked experimental at 3.1 GA: composition is algorithmic (the surface picks combinations and reports per-asset breakdowns), and there's no clean v1-translatable equivalent. Buyers ship asset pools rather than rendered creatives; the surface's per-impression composition cannot be predicted by `validate_input`. Adopters SHOULD validate behavior per surface (Google PMax vs Meta Advantage+ creative differ meaningfully)."
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — algorithmic asset-pool composition (Google PMax / Meta Advantage+ creative) wasn't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Any | None = [
        {
            'asset_group_id': 'headlines',
            'asset_type': 'text',
            'required': True,
            'min': 3,
            'max': 15,
        },
        {
            'asset_group_id': 'long_headlines',
            'asset_type': 'text',
            'required': False,
            'min': 1,
            'max': 5,
        },
        {
            'asset_group_id': 'descriptions',
            'asset_type': 'text',
            'required': True,
            'min': 2,
            'max': 5,
        },
        {
            'asset_group_id': 'images_landscape',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {
            'asset_group_id': 'images_square',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {
            'asset_group_id': 'images_vertical',
            'asset_type': 'image',
            'required': False,
            'min': 1,
            'max': 20,
        },
        {'asset_group_id': 'video', 'asset_type': 'video', 'required': False, 'min': 0, 'max': 5},
        {
            'asset_group_id': 'logo',
            'asset_type': 'image',
            'required': True,
            'min': 1,
            'max': 5,
            'logo_slots': [
                'logo_card_light',
                'logo_card_dark',
                'marketplace_listing',
                'ad_end_card',
            ],
            'required_logo_slots': ['logo_card_light', 'logo_card_dark'],
        },
        {
            'asset_group_id': 'landing_page_url',
            'asset_type': 'url',
            'required': True,
            'min': 1,
            'max': 1,
        },
    ]
    headlines_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    headlines_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    long_headlines_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    long_headlines_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    long_headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    descriptions_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    descriptions_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    description_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    images_landscape_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_landscape_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_landscape_aspect_ratio: str | None = None
    images_square_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_square_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_vertical_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    images_vertical_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    videos_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    videos_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    video_min_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    video_max_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    logo_min: Annotated[SchemaInt | None, Field(ge=0)] = None
    logo_max: Annotated[SchemaInt | None, Field(ge=0)] = None
    logo_aspect_ratios: list[str] | None = None
    business_name_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    asset_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    supports_catalog_input: Annotated[
        StrictBool | None,
        Field(
            description='Whether the product can additionally consume a catalog reference (e.g., PMax with product feed).'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var asset_image_max_file_size_kb : int | None
var business_name_max_chars : int | None
var description_max_chars : int | None
var descriptions_max : int | None
var descriptions_min : int | None
var experimental : typing.Any | None
var headline_max_chars : int | None
var headlines_max : int | None
var headlines_min : int | None
var images_landscape_aspect_ratio : str | None
var images_landscape_max : int | None
var images_landscape_min : int | None
var images_square_max : int | None
var images_square_min : int | None
var images_vertical_max : int | None
var images_vertical_min : int | None
var logo_aspect_ratios : list[str] | None
var logo_max : int | None
var logo_min : int | None
var long_headline_max_chars : int | None
var long_headlines_max : int | None
var long_headlines_min : int | None
var model_config
var slots : typing.Any | None
var supports_catalog_input : bool | None
var v1_translatable : typing.Any | None
var video_max_duration_ms : int | None
var video_min_duration_ms : int | None
var videos_max : int | None
var videos_min : int | None

Inherited members

class Params12 (**data: Any)
Expand source code
class Params12(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description="Marked experimental at 3.1 GA: the canonical's tracking model (mention-level impression + attribution, postback shape, cross-surface dedup) is intentionally underspecified for 3.1. Adopters claiming `agent_placement` ship private tracking integrations; buyer agents MUST treat attribution as adapter-defined until the 3.2 tracking-macro spec lands. Promotion to non-experimental gated on the 3.2 tracking-contract spec."
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — AI-surface sponsored mentions weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Annotated[
        Any | None,
        Field(
            description="agent_placement has minimal buyer-shipped slots — the surface composes the rendered output from brand context (resolved via the manifest's top-level `brand` BrandRef) plus optional offering_ref and landing_page_url assets. None of these assets are rendered verbatim by the buyer; the agent chooses how to use them."
        ),
    ] = [
        {'asset_group_id': 'offering_ref', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    output_modality: Annotated[
        OutputModality | None,
        Field(
            description='How the surface presents the mention. `text` = inline text (chat, search snippet). `audio` = TTS-synthesized voice. `card` = structured card with optional image + text.'
        ),
    ] = None
    max_mention_length_chars: Annotated[
        SchemaInt | None,
        Field(
            description='For text output: maximum length of the surface-composed mention text.',
            ge=1,
        ),
    ] = None
    max_mention_duration_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For audio output: maximum duration of the spoken mention in milliseconds.',
            ge=1,
        ),
    ] = None
    supports_offering_reference: Annotated[
        StrictBool | None,
        Field(
            description='Whether the product accepts an offering reference (specific product/service to promote within the mention) in addition to brand context.'
        ),
    ] = None
    supports_landing_page_url: Annotated[
        StrictBool | None,
        Field(
            description='Whether the surface attaches a landing page URL to the mention (citation, learn-more link).'
        ),
    ] = None
    tone_constraints: Annotated[
        list[str] | None,
        Field(
            description="**Advisory only.** Buyer-declared brand-voice preferences the surface SHOULD honor (e.g., ['formal', 'no_superlatives']). LLM/agentic surfaces have no protocol-level mechanism to verify enforcement — adopters that need hard guarantees should rely on brand.json voice declarations and post-mention review rather than this field. Future revisions may tie this to a structured tone vocabulary; for now treat as free-text guidance."
        ),
    ] = None
    disclosure_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the surface must include an explicit sponsorship disclosure label.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var disclosure_required : bool | None
var experimental : typing.Any | None
var max_mention_duration_ms : int | None
var max_mention_length_chars : int | None
var model_config
var output_modality : OutputModality | None
var slots : typing.Any | None
var supports_landing_page_url : bool | None
var supports_offering_reference : bool | None
var tone_constraints : list[str] | None
var v1_translatable : typing.Any | None

Inherited members

class Params13 (**data: Any)
Expand source code
class Params13(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Experimental in AdCP 3.2 while the creative working group gathers implementation evidence across premium web and mobile/app sellers.'
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description='No v1 named-format equivalent can express multiple seller-rendered states and their breakpoint bindings.'
        ),
    ] = False
    since_version: Any | None = '3.2'
    composition_model: Any | None = 'deterministic'
    supply_mode: Annotated[
        SupplyMode | None,
        Field(
            description='Which end of the template contract the buyer feeds. `components`: buyer supplies component slots; seller renders states (no `state_canvases`/`layered_source` assets allowed). `rendered_canvases`: buyer supplies exactly one `state_canvases` image per declared state × breakpoint pair. `layered_source`: buyer ships design source (+ optional `font_files`); seller production derives states (`production_window_business_days` applies) — transitional for sellers without executable templates.'
        ),
    ] = SupplyMode.components
    slots: Annotated[
        Any | None,
        Field(
            description='Default manifest slots; which are consumed depends on `supply_mode`. `state_canvases` images MUST carry `state_id` and `breakpoint_id`, and `state_click_urls` entries MUST carry `state_id` (semantic validators resolve the bindings). Component images SHOULD carry `focal_point` for deterministic seller cropping. `landing_page_url` is the default destination (see `clickthrough`). `font_files` MUST contain only buyer-licensed fonts; publisher-proprietary fonts never travel in manifests. Only image, video, text, url, zip, and pixel_tracker slot asset types are accepted — executable types (javascript, html, css, webhook) are rejected even via `slots` overrides.'
        ),
    ] = [
        {'asset_group_id': 'state_canvases', 'asset_type': 'image', 'required': False, 'min': 1},
        {'asset_group_id': 'logo', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'imagery', 'asset_type': 'image', 'required': False, 'min': 0},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'messaging', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'legal_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'video_main', 'asset_type': 'video', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'state_click_urls', 'asset_type': 'url', 'required': False, 'min': 0},
        {'asset_group_id': 'layered_source', 'asset_type': 'zip', 'required': False},
        {'asset_group_id': 'font_files', 'asset_type': 'zip', 'required': False},
    ]
    states: Annotated[
        list[State],
        Field(
            description='Finite visual states known at buy time; state and breakpoint IDs form the canvas-key matrix. Runtime causes live in `transitions[]`. A single-state unit (topscroll, interscroller, skin) declares one state, no transitions, and typically a `reveal` mechanic.',
            min_length=1,
        ),
    ]
    initial_state_id: Annotated[
        str,
        Field(
            description='State rendered when the unit first becomes visible. MUST resolve to `states[].state_id`; for a single-state unit it MUST equal the sole state.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    reveal: Annotated[
        Reveal | None,
        Field(
            description='How the unit enters view, distinct from state changes. `clip_window`: canvas fixed and progressively exposed through a scrolling window (interscroller, topscroll). `scroll_parallax`: canvas moves at a different rate than content. Reveal is presentation of one canvas, not a transition; do not fabricate a second state to express it.'
        ),
    ] = Reveal.none
    transitions: Annotated[
        list[Transitions | Transitions1 | Transitions2 | Transitions3 | Transitions4 | Transitions5]
        | None,
        Field(
            description='Bounded seller-rendered transitions between declared visual states. Required when `states` has more than one entry; MUST be omitted for single-state units. Every non-initial state MUST be reachable from `initial_state_id`. Dismissal is terminal unit behavior declared by `user_controls.dismissible`, not a hidden visual state.',
            min_length=1,
        ),
    ] = None
    clickthrough: Annotated[
        Clickthrough | None,
        Field(
            description='Destination policy. `required` (default): manifest MUST supply `landing_page_url`. `optional`: click-optional units (in-feed brand units) may omit it. `none`: unit is non-clickable; manifests MUST NOT supply `landing_page_url` or `state_click_urls`. Per-state overrides via `state_click_urls` entries carrying `state_id`; `landing_page_url` is the fallback for unlisted states.'
        ),
    ] = Clickthrough.required
    user_controls: Annotated[
        UserControls,
        Field(
            description="When any state anchors as `overlay` or `fullscreen_overlay`, either `dismissible` MUST be true or that state's `close_affordance` MUST be true (dismissibility floor; semantic validators enforce)."
        ),
    ]
    canvas_constraints: Annotated[
        list[canvas_constraint.CanvasConstraint] | None,
        Field(
            description='Rectangular areas constraining buyer artwork. Omitted state/breakpoint selectors apply the constraint to every canvas. For fluid or range-sized breakpoints, use percent-unit regions.'
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='Accepted embedded-video duration [min, max]. `duration_ms_exact` takes precedence when both are present.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[SchemaInt | None, Field(ge=1)] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description='Embedded-video aspect ratio.',
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    containers: list[Container] | None = None
    video_playback: VideoPlayback | None = None
    max_initial_load_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_subload_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Ceiling on assets loaded after the window load event (IAB LEAN subload). Pairs with `max_initial_load_kb` to mirror the New Ad Portfolio initial/subload weight pair.',
            ge=1,
        ),
    ] = None
    polite_load: Annotated[
        StrictBool | None,
        Field(
            description="When true, non-initial assets load only after the host page's window load event (IAB LEAN subload boundary)."
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var aspect_ratio : str | None
var canvas_constraints : list[CanvasConstraint] | None
var clickthrough : Clickthrough | None
var composition_model : typing.Any | None
var containers : list[Container] | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var experimental : typing.Any | None
var initial_state_id : str
var max_initial_load_kb : int | None
var max_subload_kb : int | None
var model_config
var polite_load : bool | None
var reveal : Reveal | None
var since_version : typing.Any | None
var slots : typing.Any | None
var states : list[State]
var supply_mode : SupplyMode | None
var transitions : list[Transitions | Transitions1 | Transitions2 | Transitions3 | Transitions4 | Transitions5] | None
var user_controls : UserControls
var v1_translatable : typing.Any | None
var video_playback : VideoPlayback | None

Inherited members

class Params2 (**data: Any)
Expand source code
class Params2(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for html5 canonical. Buyer ships a zip bundle plus optional backup image (required when `backup_image_required: true`) and clickthrough URL. The zip's entry point is typically `index.html`; click handling uses the `clickTag` (or `clickTAG`) macro substituted by the seller at serve time."
        ),
    ] = [
        {'asset_group_id': 'html5_bundle', 'asset_type': 'zip', 'required': True},
        {'asset_group_id': 'backup_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Required banner width in pixels — use for fixed-size slots. For multi-size flexible slots use `sizes[]`; for responsive use `min_width`/`max_width`/`min_height`/`max_height`. Exactly one of `(width, height)`, `sizes[]`, or `min/max_width` + `min/max_height` ranges MUST be set.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Required banner height in pixels. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description='List of accepted (width, height) pairs for a multi-size flexible slot (publisher banner that accepts 300×250 OR 728×90 OR 970×250). Mirrors OpenRTB `banner.format[]`. Mutually exclusive with `(width, height)` and with responsive ranges.',
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted width for responsive HTML5 banners that adapt within a range. Pair with `max_width`. Mutually exclusive with `(width, height)` and `sizes[]`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width for responsive HTML5 banners. Pair with `min_width`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height for responsive HTML5 banners. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height for responsive HTML5 banners. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    max_initial_load_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum initial-load file size (zip + above-the-fold assets) in kilobytes. IAB display standards: 200 KB for fixed sizes, 100 KB for mobile.',
            ge=1,
        ),
    ] = None
    max_polite_load_kb: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum polite-load file size after host-initiated subload, in kilobytes. IAB display standards: 500 KB for fixed sizes.',
            ge=1,
        ),
    ] = None
    host_initiated_subload: Annotated[
        StrictBool | None,
        Field(
            description='Whether the host page must initiate the polite-load phase. IAB-compliant banners require true.'
        ),
    ] = None
    max_animation_duration_ms: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum total animation duration in milliseconds. IAB standard: 30000 (30 seconds).',
            ge=0,
        ),
    ] = None
    max_cpu_load_percent: Annotated[
        SchemaInt | None,
        Field(description='Maximum CPU load percentage during render.', ge=1, le=100),
    ] = None
    mraid_required: Annotated[
        StrictBool | None,
        Field(description='Whether MRAID compatibility is required (mobile in-app).'),
    ] = None
    mraid_version: Annotated[
        MraidVersion | None,
        Field(description='Required MRAID version when mraid_required is true.'),
    ] = None
    om_sdk_required: Annotated[
        StrictBool | None,
        Field(description='Whether IAB Open Measurement SDK integration is required.'),
    ] = None
    clicktag_macro: Annotated[
        ClicktagMacro | None, Field(description='Name of the click-tag macro the bundle must use.')
    ] = None
    backup_image_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether a backup image must accompany the zip for non-HTML5 environments.'
        ),
    ] = None
    backup_image_max_size_kb: Annotated[
        SchemaInt | None, Field(description='Maximum backup image file size in kilobytes.', ge=1)
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var backup_image_max_size_kb : int | None
var backup_image_required : bool | None
var clicktag_macro : ClicktagMacro | None
var height : int | None
var host_initiated_subload : bool | None
var max_animation_duration_ms : int | None
var max_cpu_load_percent : int | None
var max_height : int | None
var max_initial_load_kb : int | None
var max_polite_load_kb : int | None
var max_width : int | None
var min_height : int | None
var min_width : int | None
var model_config
var mraid_required : bool | None
var mraid_version : MraidVersion | None
var om_sdk_required : bool | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var width : int | None

Inherited members

class Params3 (**data: Any)
Expand source code
class Params3(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description='Backward-compatible URL-delivery slots. `tag_url` MUST use `url_type: ad_request`. A format option accepting `inline_markup` or `paired_redirect` overrides this list with a required slot whose `asset_type` is `display_tag`; the display-tag asset keeps paired redirect URLs atomic.'
        ),
    ] = [
        {'asset_group_id': 'tag_url', 'asset_type': 'url', 'required': True},
        {'asset_group_id': 'backup_image', 'asset_type': 'image', 'required': False},
    ]
    width: Annotated[
        SchemaInt | None,
        Field(
            description='Required tag rendering width in pixels — use for fixed-size slots. For multi-size flexible slots use `sizes[]`; for responsive use `min_width`/`max_width`/`min_height`/`max_height`. Exactly one of `(width, height)`, `sizes[]`, or `min/max_width` + `min/max_height` ranges MUST be set.',
            ge=1,
        ),
    ] = None
    height: Annotated[
        SchemaInt | None,
        Field(
            description='Required tag rendering height in pixels. See `width` for size-mode mutual exclusion.',
            ge=1,
        ),
    ] = None
    sizes: Annotated[
        list[Size] | None,
        Field(
            description="List of accepted (width, height) pairs for a multi-size flexible slot. The buyer's third-party tag must render at one of the listed sizes; the seller picks which size to request at impression time. Mutually exclusive with `(width, height)` and with responsive ranges.",
            min_length=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted width for responsive third-party tags. Pair with `max_width`. Mutually exclusive with `(width, height)` and `sizes[]`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted width for responsive third-party tags. Pair with `min_width`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum accepted height for responsive third-party tags. Pair with `max_height`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum accepted height for responsive third-party tags. Pair with `min_height`.',
            ge=1,
        ),
    ] = None
    supported_tag_types: Annotated[
        list[SupportedTagType] | None,
        Field(
            deprecated=True,
            description='Deprecated ambiguous mechanism list. Use `supported_delivery_types`; markup subtype lives on the `display_tag` asset.',
        ),
    ] = None
    supported_delivery_types: Annotated[
        list[SupportedDeliveryType] | None,
        Field(
            description='Closed set of delivery types this format option can traffic. `paired_redirect` means one atomic ad-request/click-through pair (Internal Redirect semantics), never independently matchable URL slots.',
            min_length=1,
        ),
    ] = None
    ssl_required: Annotated[
        StrictBool | None, Field(description='Whether the tag URL must be HTTPS.')
    ] = None
    max_redirect_depth: Annotated[
        SchemaInt | None, Field(description='Maximum redirect chain depth permitted.', ge=0)
    ] = None
    max_response_time_ms: Annotated[
        SchemaInt | None,
        Field(description='Maximum tag-server response time in milliseconds.', ge=1),
    ] = None
    backup_image_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether a backup image must accompany the tag for environments that cannot render the third-party tag.'
        ),
    ] = None
    backup_image_max_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    om_sdk_required: Annotated[
        StrictBool | None,
        Field(
            description="Whether the buyer's tag must integrate IAB Open Measurement SDK for viewability."
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var backup_image_max_size_kb : int | None
var backup_image_required : bool | None
var height : int | None
var max_height : int | None
var max_redirect_depth : int | None
var max_response_time_ms : int | None
var max_width : int | None
var min_height : int | None
var min_width : int | None
var model_config
var om_sdk_required : bool | None
var sizes : list[Size] | None
var slots : typing.Any | None
var ssl_required : bool | None
var supported_delivery_types : list[SupportedDeliveryType] | None
var supported_tag_types : list[SupportedTagType] | None
var width : int | None

Inherited members

class Params4 (**data: Any)
Expand source code
class Params4(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — multi-card carousels (Meta carousel, Pinterest pin collections, Snap collection ads) weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural."
        ),
    ] = False
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for image_carousel. The `cards` slot's value in the manifest is an array of [card-asset](/schemas/core/assets/card-asset.json) objects; `min` / `max` constrain card count."
        ),
    ] = [
        {'asset_group_id': 'cards', 'asset_type': 'card', 'required': True, 'min': 2, 'max': 10},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    card_aspect_ratio: Annotated[
        str | None,
        Field(
            description="Aspect ratio shared across all cards (e.g., '1:1', '1.91:1', '4:5').",
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    min_cards: Annotated[
        SchemaInt | None, Field(description='Minimum card count (typical: 2 or 3).', ge=2)
    ] = None
    max_cards: Annotated[
        SchemaInt | None,
        Field(description='Maximum card count (typical: 6, 10, or 35 depending on platform).'),
    ] = None
    allowed_card_media_asset_types: Annotated[
        list[AllowedCardMediaAssetType] | None,
        Field(
            description='Asset types each card\'s `media` field may carry. Default: [\'image\']. Polymorphic carousels (Meta) allow [\'image\', \'video\']. Renamed from `allowed_card_asset_types` to disambiguate that this constrains the card\'s media payload, not the card-asset itself (which is always asset_type: "card").'
        ),
    ] = None
    allowed_card_asset_types: Annotated[
        list[AllowedCardMediaAssetType] | None,
        Field(
            deprecated=True,
            description='DEPRECATED — alias for `allowed_card_media_asset_types`. Kept for back-compat; prefer the new field name. Removed in 5.0.',
        ),
    ] = None
    card_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    card_video_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    card_video_max_duration_ms: Annotated[SchemaInt | None, Field(ge=1)] = None
    primary_text_max_chars: Annotated[
        SchemaInt | None,
        Field(description='Maximum length of the carousel-level primary text.', ge=1),
    ] = None
    card_headline_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Per-card headline character limit. Governs the `headline` field on each card-asset in the `cards` slot.',
            ge=1,
        ),
    ] = None
    card_description_max_chars: Annotated[
        SchemaInt | None,
        Field(
            description='Per-card description character limit. Governs the `description` field on each card-asset in the `cards` slot. Distinct from `card_headline_max_chars`: description is longer body copy (typically 100-500 chars); headline is the short label (typically 25-40 chars).',
            ge=1,
        ),
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var allowed_card_asset_types : list[AllowedCardMediaAssetType] | None
var allowed_card_media_asset_types : list[AllowedCardMediaAssetType] | None
var card_aspect_ratio : str | None
var card_description_max_chars : int | None
var card_headline_max_chars : int | None
var card_image_max_file_size_kb : int | None
var card_video_max_duration_ms : int | None
var card_video_max_file_size_kb : int | None
var max_cards : int | None
var min_cards : int | None
var model_config
var primary_text_max_chars : int | None
var slots : typing.Any | None
var ssl_required : bool | None
var v1_translatable : typing.Any | None

Inherited members

class Params5 (**data: Any)
Expand source code
class Params5(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description='Default slots for video_hosted canonical. Buyer ships a video asset (file or hosted URL); optional headline, primary text (long-form caption), CTA (typically constrained via `cta_values`), brand_name (typical for vertical short-form), companion_banner (typical for horizontal instream), and clickthrough URL. Products MAY override or extend the default — e.g., remove `companion_banner` for short-form vertical, narrow `cta` to a value enum, mark `landing_page_url` as required.'
        ),
    ] = [
        {'asset_group_id': 'video_main', 'asset_type': 'video', 'required': True},
        {'asset_group_id': 'headline', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'primary_text', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'cta', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'brand_name', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'companion_banner', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    orientation: Annotated[
        Orientation | None,
        Field(
            description='Video orientation. Vertical = 9:16 (Reels, Stories, Shorts). Horizontal = 16:9 (instream, CTV). Square = 1:1 (in-feed).'
        ),
    ] = None
    aspect_ratio: Annotated[
        str | None,
        Field(
            description='Aspect ratio. Inferred from orientation if omitted.',
            pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$',
        ),
    ] = None
    min_width: Annotated[SchemaInt | None, Field(ge=1)] = None
    min_height: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_width: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_height: Annotated[SchemaInt | None, Field(ge=1)] = None
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='[min, max] duration in milliseconds. Either endpoint MAY be null to express an unbounded side: [null, 60000] means up to 60s; [15000, null] means at least 15s. [null, null] is invalid because at least one endpoint must be bounded. **Precedence**: when both `duration_ms_exact` and `duration_ms_range` ship on the same product, `duration_ms_exact` takes precedence — buyers MUST validate against the exact value and ignore the range. SDKs SHOULD lint a warning when both fields ship; producers SHOULD pick one.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship (see `duration_ms_range` description).',
            ge=1,
        ),
    ] = None
    video_codecs: list[VideoCodec] | None = None
    audio_codecs: list[AudioCodec] | None = None
    containers: list[Container] | None = None
    min_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_file_size_mb: Annotated[
        SchemaInt | None,
        Field(description='Maximum file size, where 1 MB is exactly 1,000,000 bytes.', ge=1),
    ] = None
    frame_rates: list[StrictFloat] | None = None
    captions: Captions | None = None
    om_sdk_required: StrictBool | None = None
    headline_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    primary_text_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    brand_name_max_chars: Annotated[SchemaInt | None, Field(ge=1)] = None
    cta_values: list[str] | None = None
    companion_banner_widths: Annotated[
        list[CompanionBannerWidth] | None,
        Field(description='Permitted companion banner widths (instream video).'),
    ] = None
    companion_banner_heights: list[CompanionBannerHeight] | None = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description='Where the rendered asset bytes come from. Single shared enum across canonicals. See `image.json#asset_source` for the full semantics. `publisher_host_recorded` is audio-specific and has no defined behavior on video. `publisher_owned_reference` is valid when the product accepts an existing post reference via a `published_post` slot instead of uploaded video bytes. Adopters MUST select a value appropriate to the canonical.'
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description='Whether the product accepts buyer-uploaded video. When `rejected`, the buyer cannot ship a video asset directly — they must use build_creative, sync_creatives with brief inputs, or sync_creatives with an accepted reference asset so the seller produces or resolves the video.'
        ),
    ] = BuyerAssetAcceptance.accepted
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `video_hosted` only `screensaver` is valid (ambient looping video the platform plays on idle). Other experiences route per the matrix in docs/creative/ctv-experiences.mdx; linear CTV video declares no experience.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var aspect_ratio : str | None
var asset_source : AssetSource | None
var audio_codecs : list[AudioCodec] | None
var brand_name_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var captions : Captions | None
var companion_banner_heights : list[CompanionBannerHeight] | None
var companion_banner_widths : list[CompanionBannerWidth] | None
var containers : list[Container] | None
var cta_values : list[str] | None
var ctv_ad_experience : CtvAdExperience | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var frame_rates : list[float] | None
var headline_max_chars : int | None
var max_bitrate_kbps : int | None
var max_file_size_mb : int | None
var max_height : int | None
var max_width : int | None
var min_bitrate_kbps : int | None
var min_height : int | None
var min_width : int | None
var model_config
var om_sdk_required : bool | None
var orientation : Orientation | None
var primary_text_max_chars : int | None
var slots : typing.Any | None
var video_codecs : list[VideoCodec] | None

Inherited members

class Params6 (**data: Any)
Expand source code
class Params6(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for video_vast canonical. Buyer ships a VAST tag (URL or inline XML, VAST 2.x-4.x) plus an optional clickthrough URL (which falls back to the VAST `ClickThrough` element when omitted). Tracking events are inherent to VAST and don't require explicit slots."
        ),
    ] = [
        {'asset_group_id': 'vast_tag', 'asset_type': 'vast', 'required': True},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    orientation: Orientation | None = None
    aspect_ratio: Annotated[
        str | None, Field(pattern='^[0-9]+(\\.[0-9]+)?:[0-9]+(\\.[0-9]+)?$')
    ] = None
    vast_versions: Annotated[
        list[vast_version_1.VastVersion] | None,
        Field(
            description='VAST versions accepted by this product format option. The asset still declares exactly one `vast_version`; compatibility requires membership in this set and the seller-wide execution set.',
            min_length=1,
        ),
    ] = None
    vast_version: Annotated[
        vast_version_1.VastVersion | None,
        Field(
            deprecated=True,
            description='Deprecated one-element alias for `vast_versions`. Producers use either the singular legacy alias or the plural 3.2 field, never both.',
        ),
    ] = None
    media_file_requirements: Annotated[
        vast_media_file_requirements.VastMediafileRequirements | None,
        Field(
            description='Technical acceptance constraints for alternative VAST MediaFile renditions. Each applicable resolved InLine linear creative needs at least one MediaFile satisfying all declared constraints.'
        ),
    ] = None
    vpaid_enabled: Annotated[
        StrictBool | None,
        Field(
            description='Whether VPAID interactivity is supported. When true, the VAST tag may carry VPAID JS/Flash payloads.'
        ),
    ] = None
    vpaid_version: VpaidVersion | None = None
    simid_supported: Annotated[
        StrictBool | None,
        Field(
            description='Whether the seller accepts IAB SIMID through `<InteractiveCreativeFile apiFramework="SIMID">` on a Linear VAST creative. SIMID is not a generic VAST extension and cannot be serialized under NonLinearAds; every `ctv_ad_experience` profile therefore forbids `true`.'
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRangeItem] | None,
        Field(
            description='[min, max] duration in milliseconds. **Precedence**: `duration_ms_exact` takes precedence when both ship. SDKs SHOULD lint a warning when both fields ship.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    min_width: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum placement/player width in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    max_width: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum placement/player width in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    min_height: Annotated[
        SchemaInt | None,
        Field(
            description='Minimum placement/player height in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    max_height: Annotated[
        SchemaInt | None,
        Field(
            description='Maximum placement/player height in pixels. MediaFile rendition dimensions are declared in `media_file_requirements`.',
            ge=1,
        ),
    ] = None
    creative_type: Annotated[
        CreativeType | None,
        Field(
            description='Required VAST creative class: `linear` (in-stream Linear), `nonlinear` (NonLinearAds overlay-class), or `either`. Supersedes `linear_required`; when both are present `creative_type` wins, and validators treat `linear_required: true` with no `creative_type` as `linear`.'
        ),
    ] = None
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option is eligible to serve. On video_vast only `pause`, `screensaver`, `overlay`, `squeezeback`, and `in_scene` are valid (`menu` routes to native_in_feed or sponsored_placement), and `creative_type` MUST be `nonlinear`. Because VAST places `<InteractiveCreativeFile>` only under Linear `<MediaFiles>`, `simid_supported` MUST NOT be true on any of these NonLinear profiles. Per-experience floors: `overlay` and `squeezeback` require a 10s minimum duration; `in_scene` requires a 3s minimum brand-exposure duration and forbids interactivity (`vpaid_enabled` MUST NOT be true); `pause` has no duration floor and ends on viewer or device action.'
        ),
    ] = None
    motion_level: Annotated[
        motion_level_1.CreativeMotionLevel | None,
        Field(description='Accepted motion class for the rendered creative (AdCOM attrs 21-23).'),
    ] = None
    activation_methods: Annotated[
        list[activation_method.CreativeActivationMethod] | None,
        Field(
            description='Viewer activation mechanisms this option offers. Activations are engagement events, not impressions.'
        ),
    ] = None
    linear_required: Annotated[
        StrictBool | None,
        Field(
            description='Whether the VAST creative must be linear (non-skippable in-stream). Superseded by `creative_type`; retained for pre-3.2 declarations.'
        ),
    ] = None
    skippable_after_ms: Annotated[
        SchemaInt | None,
        Field(
            description='When skippable, the buyer-side skip threshold in milliseconds (e.g., 5000 for 5-second skippable pre-roll).',
            ge=0,
        ),
    ] = None
    max_wrapper_depth: Annotated[
        SchemaInt | None, Field(description='Maximum VAST wrapper redirect depth permitted.', ge=0)
    ] = None
    ssl_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var activation_methods : list[CreativeActivationMethod] | None
var aspect_ratio : str | None
var creative_type : CreativeType | None
var ctv_ad_experience : CtvAdExperience | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRangeItem] | None
var linear_required : bool | None
var max_height : int | None
var max_width : int | None
var max_wrapper_depth : int | None
var media_file_requirements : VastMediafileRequirements | None
var min_height : int | None
var min_width : int | None
var model_config
var motion_level : CreativeMotionLevel | None
var orientation : Orientation | None
var simid_supported : bool | None
var skippable_after_ms : int | None
var slots : typing.Any | None
var ssl_required : bool | None
var vast_version : VastVersion | None
var vast_versions : list[VastVersion] | None
var vpaid_enabled : bool | None
var vpaid_version : VpaidVersion | None

Inherited members

class Params7 (**data: Any)
Expand source code
class Params7(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for buyer-uploaded audio. Host-read products override with a `script` (asset_type: text) or `creative_brief` (asset_type: brief) slot in place of `audio_main`, plus `asset_source: 'publisher_host_recorded'` and `buyer_asset_acceptance: 'rejected'`. TTS-from-script products override similarly with `asset_source: 'seller_pre_rendered_from_brief'`."
        ),
    ] = [
        {'asset_group_id': 'audio_main', 'asset_type': 'audio', 'required': True},
        {'asset_group_id': 'companion_image', 'asset_type': 'image', 'required': False},
        {'asset_group_id': 'brand_name', 'asset_type': 'text', 'required': False},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    duration_ms_range: Annotated[
        list[DurationMsRange | None] | None,
        Field(
            description='[min, max] duration in milliseconds. Either endpoint MAY be null to express an unbounded side: [null, 60000] means up to 60s; [15000, null] means at least 15s. [null, null] is invalid because at least one endpoint must be bounded. **Precedence**: when both `duration_ms_exact` and `duration_ms_range` ship on the same product, `duration_ms_exact` takes precedence — buyers MUST validate against the exact value and ignore the range. SDKs SHOULD lint a warning when both fields ship; producers SHOULD pick one.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    audio_codecs: list[AudioCodec2] | None = None
    audio_sample_rates: list[AudioSampleRate] | None = None
    audio_channels: list[AudioChannel] | None = None
    min_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_bitrate_kbps: Annotated[SchemaInt | None, Field(ge=1)] = None
    max_file_size_mb: Annotated[
        StrictFloat | None,
        Field(
            description='Maximum hosted audio file size in decimal megabytes. Agents that proxy or cache media SHOULD advertise their effective transport ceiling here.',
            gt=0.0,
        ),
    ] = None
    loudness_lufs: Annotated[
        StrictFloat | None,
        Field(
            description='Required integrated loudness in LUFS (typical: -16 for streaming/podcast, -23 for broadcast). Negative values.'
        ),
    ] = None
    loudness_tolerance_db: Annotated[
        StrictFloat | None,
        Field(description='Permitted deviation from loudness_lufs in dB.', ge=0.0),
    ] = None
    true_peak_dbfs: Annotated[
        StrictFloat | None, Field(description='Maximum true-peak level in dBFS (typical: -2).')
    ] = None
    asset_source: Annotated[
        AssetSource | None,
        Field(
            description="Where the rendered audio bytes come from. Single shared enum across canonicals (see `image.json#asset_source` for the full semantics). `publisher_host_recorded`: the publisher's host records the audio (podcast host-read pattern); buyer must use the publisher's build_creative capability. `publisher_owned_reference` is valid only when the product accepts a reference asset whose publisher-owned source resolves to playable audio. `publisher_host_recorded` remains the normal audio-specific host-read value."
        ),
    ] = AssetSource.buyer_uploaded
    buyer_asset_acceptance: Annotated[
        BuyerAssetAcceptance | None,
        Field(
            description="Whether the product accepts buyer-uploaded audio. When `rejected`, the buyer cannot ship an audio asset directly — they must use build_creative (or sync_creatives with brief inputs) so the seller produces the audio. Combined with `asset_source`, lets a product declare 'I produce audio from briefs and refuse buyer uploads' (asset_source=`seller_pre_rendered_from_brief`, buyer_asset_acceptance=`rejected`)."
        ),
    ] = BuyerAssetAcceptance.accepted
    companion_image_required: StrictBool | None = None
    companion_image_aspect_ratio: str | None = None
    companion_image_max_file_size_kb: Annotated[SchemaInt | None, Field(ge=1)] = None
    brand_name_max_chars: Annotated[SchemaInt | None, Field(ge=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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var asset_source : AssetSource | None
var audio_channels : list[AudioChannel] | None
var audio_codecs : list[AudioCodec2] | None
var audio_sample_rates : list[AudioSampleRate] | None
var brand_name_max_chars : int | None
var buyer_asset_acceptance : BuyerAssetAcceptance | None
var companion_image_aspect_ratio : str | None
var companion_image_max_file_size_kb : int | None
var companion_image_required : bool | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRange | None] | None
var loudness_lufs : float | None
var loudness_tolerance_db : float | None
var max_bitrate_kbps : int | None
var max_file_size_mb : float | None
var min_bitrate_kbps : int | None
var model_config
var slots : typing.Any | None
var true_peak_dbfs : float | None

Inherited members

class Params8 (**data: Any)
Expand source code
class Params8(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    slots: Annotated[
        Any | None,
        Field(
            description="Default slots for audio_daast canonical. Buyer ships a DAAST tag (URL or inline XML, 1.0 or 1.1) plus an optional clickthrough URL. Tracking events are inherent to DAAST and don't require explicit slots."
        ),
    ] = [
        {'asset_group_id': 'daast_tag', 'asset_type': 'daast', 'required': True},
        {'asset_group_id': 'landing_page_url', 'asset_type': 'url', 'required': False},
    ]
    daast_version: Annotated[
        daast_version_1.DaastVersion | None,
        Field(
            deprecated=True,
            description='Deprecated one-element alias for `daast_versions`. Producers use either the singular legacy alias or the plural 3.2 field, never both.',
        ),
    ] = None
    daast_versions: Annotated[
        daast_tracker_constraints.DaastVersions | None,
        Field(
            description="Accepted DAAST versions for this format option. A tracker execution selector's daast_versions must be a nonempty subset of this set."
        ),
    ] = None
    duration_ms_range: Annotated[
        list[DurationMsRangeItem] | None,
        Field(
            description='[min, max] duration in milliseconds. **Precedence**: `duration_ms_exact` takes precedence when both ship. SDKs SHOULD lint a warning when both fields ship.',
            max_length=2,
            min_length=2,
        ),
    ] = None
    duration_ms_exact: Annotated[
        SchemaInt | None,
        Field(
            description='When set, duration must equal exactly this value. Takes precedence over `duration_ms_range` when both ship.',
            ge=1,
        ),
    ] = None
    linear_required: StrictBool | None = None
    max_wrapper_depth: Annotated[SchemaInt | None, Field(ge=0)] = None
    ssl_required: StrictBool | None = None
    companion_image_required: StrictBool | None = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var companion_image_required : bool | None
var daast_version : DaastVersion | None
var daast_versions : DaastVersions | None
var duration_ms_exact : int | None
var duration_ms_range : list[DurationMsRangeItem] | None
var linear_required : bool | None
var max_wrapper_depth : int | None
var model_config
var slots : typing.Any | None
var ssl_required : bool | None

Inherited members

class Params9 (**data: Any)
Expand source code
class Params9(CanonicalFormatBase):
    model_config = ConfigDict(
        extra='allow',
    )
    experimental: Annotated[
        Any | None,
        Field(
            description='Marked experimental at 3.1 GA: the canonical covers 4 meaningfully different retail-media adapter contracts (Amazon SP, Criteo SP / CitrusAd SP, Pinterest Collection, generative-per-SKU). Adopter contracts vary; buyers MUST validate per-adapter behavior before routing budget. Promotion to non-experimental gated on the #4592 adapter-contract docs work.'
        ),
    ] = True
    v1_translatable: Annotated[
        Any | None,
        Field(
            description="Inherently new in v2 — retail-media catalog placements weren't expressible as v1 named formats. SDKs MUST NOT emit `FORMAT_PROJECTION_FAILED` for products using this canonical; the v1-unreachability is structural, not a registry-coverage gap."
        ),
    ] = False
    slots: Any | None = [
        {'asset_group_id': 'source_catalog', 'required': True, 'asset_type': 'catalog'},
        {'asset_group_id': 'hero_asset', 'required': False, 'asset_type': 'image'},
        {'asset_group_id': 'landing_page_url', 'required': False, 'asset_type': 'url'},
    ]
    supported_catalog_types: Annotated[
        list[catalog_type.CatalogType] | None,
        Field(description='Catalog types this product accepts.'),
    ] = None
    min_items: Annotated[
        SchemaInt | None, Field(description='Minimum catalog item count buyer must supply.', ge=1)
    ] = None
    max_items: Annotated[
        SchemaInt | None, Field(description='Maximum items considered for placement.')
    ] = None
    fanout_mode: Annotated[
        FanoutMode | None,
        Field(
            description='How items map to delivery: per_item = one ad per catalog item; multi_item_in_creative = composed multi-item ad (Pinterest Collection, Snap Collection); single_item = one ad showing one item.'
        ),
    ] = None
    required_catalog_fields: Annotated[
        list[str] | None,
        Field(
            description="Catalog item fields the seller requires (e.g., ['title', 'image_url', 'price'])."
        ),
    ] = None
    supported_id_types: Annotated[
        list[SupportedIdType] | None,
        Field(description='Catalog identifier types the placement renders against.'),
    ] = None
    hero_asset_supported: Annotated[
        StrictBool | None,
        Field(
            description='Whether the buyer can supply a hero/banner asset alongside the catalog (Pinterest Collection pattern).'
        ),
    ] = None
    item_production_model: Annotated[
        ItemProductionModel | None,
        Field(
            description='How each per-item creative is produced. Covers the same production-source axis as `asset_source` on `image` / `video_hosted` / `audio_hosted` but with a 4-value subset — drops `publisher_host_recorded` because it\'s audio-specific and doesn\'t apply to retail-media catalog placements. SDK codegen MAY share a base enum and narrow per-canonical, or emit two distinct enums; either way the wire values overlap exactly for the 4 retained values. `buyer_uploaded` (default, current Amazon/Criteo/CitrusAd pattern): the buyer\'s catalog already contains rendered assets per item; the seller composes the placement using those assets. ("Uploaded" reads slightly off for catalog-keyed items where the buyer didn\'t actively upload bytes — the catalog ingestion already supplied them — but the semantic is the same: rendered bytes are buyer-supplied, not seller-produced.) `seller_pre_rendered_from_brief`: the buyer ships a brief plus the catalog reference; the seller renders one creative per catalog item from the brief at sync_creatives time. `seller_human_designed`: seller\'s design team produces per-item renders manually. `agent_synthesized`: AI synthesis pipeline produces per-item renders; pair with `synthesis_nondeterministic: true` for Veo/Sora-class generative video applied per item. Captures the multi-output generative pattern (1 brief × N catalog items → N rendered creatives) under the existing canonical without requiring a separate canonical. Distinct from `fanout_mode`, which describes how items map to delivery slots after rendering.'
        ),
    ] = ItemProductionModel.buyer_uploaded
    ctv_ad_experience: Annotated[
        ctv_ad_experience_1.CtvAdExperience | None,
        Field(
            description='CTV experience this option serves. On `sponsored_placement`: `menu` (sponsored app/content tiles and rows whose assets derive from a catalog listing — Fire-TV-tile pattern), `squeezeback`, and `in_scene` (seller-composited brand integrations produced from the catalog/brief rather than a buyer wire creative). Asset-bundle menu heroes route to `native_in_feed`.'
        ),
    ] = 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

  • adcp.types.domains.formats.canonical._base.CanonicalFormatBase
  • AdCPBaseModel
  • pydantic.main.BaseModel

Class variables

var ctv_ad_experience : CtvAdExperience | None
var experimental : typing.Any | None
var fanout_mode : FanoutMode | None
var hero_asset_supported : bool | None
var item_production_model : ItemProductionModel | None
var max_items : int | None
var min_items : int | None
var model_config
var required_catalog_fields : list[str] | None
var slots : typing.Any | None
var supported_catalog_types : list[CatalogType] | None
var supported_id_types : list[SupportedIdType] | None
var v1_translatable : typing.Any | None

Inherited members

class ReferenceMutability (*args, **kwds)
Expand source code
class ReferenceMutability(StrEnum):
    immutable_snapshot = 'immutable_snapshot'
    mutable_requires_reapproval = 'mutable_requires_reapproval'
    mutable_auto_recheck = 'mutable_auto_recheck'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var immutable_snapshot
var mutable_auto_recheck
var mutable_requires_reapproval
class RequiredPixelRatio (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class RequiredPixelRatio(PixelRatio):
    pass

A float generated from a JSON Schema number root.

Strict, like the StrictFloat the generator emits for a type: number field: an int or float is accepted, a bool or numeric string is refused, matching the bundled JSON Schema validator.

Ancestors

  • adcp.types.domains.formats.canonical._base.PixelRatio
  • adcp.types._scalar.ScalarFloat
  • adcp.types._scalar._ScalarRoot
  • builtins.float
class ServingPolicy (*args, **kwds)
Expand source code
class ServingPolicy(StrEnum):
    seller_served_only = 'seller_served_only'
    third_party_allowed = 'third_party_allowed'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var seller_served_only
var third_party_allowed
class SharedSlot (**data: Any)
Expand source code
class SharedSlot(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_group_id: Annotated[str, Field(pattern='^[a-z0-9_]+$')]
    asset_type: AssetType
    required: StrictBool | None = False
    min: Annotated[SchemaInt | None, Field(ge=0)] = None
    max: Annotated[SchemaInt | None, Field(ge=1)] = None
    consumed_by: Annotated[
        list[str],
        Field(
            description='Component IDs that consume this shared asset. Every value MUST resolve to `components[].component_id`.',
            min_length=1,
        ),
    ]

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 asset_type : AssetType
var consumed_by : list[str]
var max : int | None
var min : int | None
var model_config
var required : bool | None

Inherited members

class Slot (**data: Any)
Expand source code
class Slot(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    asset_group_id: Annotated[
        str,
        Field(
            description='Canonical asset_group_id from /schemas/core/asset-group-vocabulary.json. Non-canonical IDs are valid but trigger soft warnings.'
        ),
    ]
    asset_type: Annotated[
        AssetType,
        Field(
            description='Discriminator selecting the asset schema this slot accepts. SDK codegen uses this to type the slot value. `display_tag` is the atomic third-party display representation (URL, inline markup, or paired redirect). `published_post` is an existing-post reference asset. `pixel_tracker` / `vast_tracker` / `daast_tracker` are renderer-fired tracker primitives. `object` is a last-resort fallback.'
        ),
    ]
    required: Annotated[
        StrictBool | None, Field(description='Whether this slot is required for a valid manifest.')
    ] = False
    min: Annotated[
        SchemaInt | None, Field(description='Minimum count for repeatable / pool slots.', ge=0)
    ] = None
    max: Annotated[
        SchemaInt | None, Field(description='Maximum count for repeatable / pool slots.', ge=1)
    ] = None
    max_chars: Annotated[
        SchemaInt | None,
        Field(
            description="Per-slot character limit. Valid only when `asset_type` is `text`, `markdown`, or `brief`. Mutually exclusive with `max_size_kb` (which applies to binary asset types). Schema enforces via if/then so a producer can't set both on the same slot.",
            ge=1,
        ),
    ] = None
    max_size_kb: Annotated[
        SchemaInt | None,
        Field(
            description="Per-slot file size limit in exact kilobytes, where 1 KB = 1,000 bytes. Valid only when `asset_type` is `image`, `video`, `audio`, or `zip`. Mutually exclusive with `max_chars` (which applies to text asset types). Schema enforces via if/then so a producer can't set both on the same slot.",
            ge=1,
        ),
    ] = None
    pixel_ratios: Annotated[
        list[PixelRatio] | None,
        Field(
            description="Accepted intrinsic-pixel densities for this image-bearing slot. Valid when `asset_type` is `image`, and on a `card` slot where it constrains each card's image media (video media is unaffected). This makes density available to every canonical carrying image assets (native, carousel, responsive, companion images, and image itself), not only `format_kind: image`. When the image canonical also declares top-level `params.pixel_ratios`, the effective set is the intersection; an empty intersection is invalid. One matching asset satisfies the slot unless `required_pixel_ratios` requires rendition coverage.",
            min_length=1,
        ),
    ] = None
    required_pixel_ratios: Annotated[
        list[RequiredPixelRatio] | None,
        Field(
            description='Required density coverage for an image rendition set. Valid only when `asset_type` is `image` and `pixel_ratios` is also declared. Every value MUST appear in the effective accepted set after intersecting any top-level image `params.pixel_ratios`, and the manifest slot value MUST be an array containing exactly one matching image rendition for each required ratio. Other accepted ratios remain optional. For example, `pixel_ratios: [1, 1.5, 2]` with `required_pixel_ratios: [1, 2]` requires the 1x and 2x renditions while making 1.5x optional. SDKs enforce intersection, subset, coverage, and duplicate-ratio rules because JSON Schema draft-07 cannot express them generically.',
            min_length=1,
        ),
    ] = None
    logo_slots: Annotated[
        list[logo_slot.LogoSlot] | None,
        Field(
            description='When `asset_group_id` is `logo`, renderer-facing brand.json logo slots acceptable for this format slot. Producers selecting from brand.json SHOULD prefer `logos[]` entries whose `slots[]` intersects this list, then apply `visual_guidelines.logo_usage_rules[]`.'
        ),
    ] = None
    required_logo_slots: Annotated[
        list[logo_slot.LogoSlot] | None,
        Field(
            description='Subset of `logo_slots` for which this format expects explicit logo coverage. A manifest or brand-derived logo pool SHOULD include at least one usable logo for each required slot; if coverage is missing, builders SHOULD surface a validation warning or approval mapping instead of guessing from prose.'
        ),
    ] = None
    description: Annotated[
        str | None,
        Field(description='Human-readable description of what the slot expects from the buyer.'),
    ] = None
    consumed_for_production: Annotated[
        StrictBool | None,
        Field(
            description="Dispatch hint for `build_creative` and v1↔v2 wire translators: when `true`, the slot's value is consumed as INPUT to a production step (host-read script, brief copy fed to generative synthesis, catalog feed driving per-SKU rendering) and is not rendered verbatim. When `false` (default), the slot's value is rendered verbatim on the placement (image bytes, video file, display tag).\n\nMotivates the v1↔v2 dispatch table: pre-v2 buyers shipped production-consumed inputs separately in a `inputs` map on the build_creative request; v2 collapses inputs and rendered assets into a single `assets` map keyed by `asset_group_id`. SDK translators between v1 and v2 use this flag per canonical to know which assets in the v2 manifest map back to v1 `inputs` vs v1 `assets`. Without the per-slot flag the dispatch table lives in adopter code and every SDK gets it slightly different.\n\nProducers SHOULD set this explicitly on slots whose consumption pattern isn't obvious (host-read scripts on `audio_hosted`, briefs on generative `video_hosted`, catalog feeds on `sponsored_placement`). For canonicals where every slot is render-verbatim (`image`, `display_tag`, `video_vast`, `audio_vast`), the default `false` is sufficient and the flag MAY be omitted."
        ),
    ] = 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 asset_group_id : str
var asset_type : adcp.types.domains.formats.canonical._base.AssetType
var consumed_for_production : bool | None
var description : str | None
var logo_slots : list[LogoSlot] | None
var max : int | None
var max_chars : int | None
var max_size_kb : int | None
var min : int | None
var model_config
var pixel_ratios : list[adcp.types.domains.formats.canonical._base.PixelRatio] | None
var required : bool | None
var required_logo_slots : list[LogoSlot] | None
var required_pixel_ratios : list[adcp.types.domains.formats.canonical._base.RequiredPixelRatio] | None

Inherited members

class TransitionMode3 (*args, **kwds)
Expand source code
class TransitionMode3(StrEnum):
    instant = 'instant'
    animated = 'animated'
    scroll_linked = 'scroll_linked'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var animated
var instant
var scroll_linked
class TransitionMode9 (*args, **kwds)
Expand source code
class TransitionMode9(StrEnum):
    instant = 'instant'
    animated = 'animated'
    scroll_linked = 'scroll_linked'

Enum where members are also (and must be) strings

Ancestors

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

Class variables

var animated
var instant
var scroll_linked
class Transitions1 (**data: Any)
Expand source code
class Transitions1(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['in_view_timer'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'in_view_timer'
    input: Annotated[
        Input | None,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = None
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ]
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input | None
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['in_view_timer']

Inherited members

class Transitions10 (**data: Any)
Expand source code
class Transitions10(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['user_action'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'user_action'
    input: Annotated[
        Input,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ]
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['user_action']

Inherited members

class Transitions11 (**data: Any)
Expand source code
class Transitions11(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['media_event'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'media_event'
    input: Annotated[
        Input | None,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = None
    media_event: Annotated[
        MediaEvent,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ]
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input | None
var media_event : MediaEvent
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['media_event']

Inherited members

class Transitions2 (**data: Any)
Expand source code
class Transitions2(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['scroll_threshold'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'scroll_threshold'
    input: Annotated[
        Literal['scroll'],
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = 'scroll'
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ]
    scroll_reference: Annotated[
        ScrollReference,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ]
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Literal['scroll']
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference
var scroll_start_percent : float | None
var scroll_threshold_percent : float
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['scroll_threshold']

Inherited members

class Transitions3 (**data: Any)
Expand source code
class Transitions3(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['scroll_progress'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'scroll_progress'
    input: Annotated[
        Literal['scroll'],
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = 'scroll'
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        Literal['scroll_linked'],
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ] = 'scroll_linked'
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ]
    scroll_start_percent: Annotated[
        StrictFloat,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ]
    scroll_end_percent: Annotated[
        StrictFloat,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ]
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Literal['scroll']
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float
var scroll_reference : ScrollReference
var scroll_start_percent : float
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : Literal['scroll_linked']
var trigger : Literal['scroll_progress']

Inherited members

class Transitions4 (**data: Any)
Expand source code
class Transitions4(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['user_action'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'user_action'
    input: Annotated[
        Input,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ]
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['user_action']

Inherited members

class Transitions5 (**data: Any)
Expand source code
class Transitions5(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['media_event'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'media_event'
    input: Annotated[
        Input | None,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = None
    media_event: Annotated[
        MediaEvent,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ]
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input | None
var media_event : MediaEvent
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['media_event']

Inherited members

class Transitions7 (**data: Any)
Expand source code
class Transitions7(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['in_view_timer'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'in_view_timer'
    input: Annotated[
        Input | None,
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = None
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ]
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference | None,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ] = None
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Input | None
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference | None
var scroll_start_percent : float | None
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['in_view_timer']

Inherited members

class Transitions8 (**data: Any)
Expand source code
class Transitions8(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['scroll_threshold'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'scroll_threshold'
    input: Annotated[
        Literal['scroll'],
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = 'scroll'
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        TransitionMode,
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ]
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ]
    scroll_reference: Annotated[
        ScrollReference,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ]
    scroll_start_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_end_percent: Annotated[
        StrictFloat | None,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Literal['scroll']
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float | None
var scroll_reference : ScrollReference
var scroll_start_percent : float | None
var scroll_threshold_percent : float
var to_state_id : str
var transition_id : str
var transition_mode : TransitionMode
var trigger : Literal['scroll_threshold']

Inherited members

class Transitions9 (**data: Any)
Expand source code
class Transitions9(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    transition_id: Annotated[
        str,
        Field(
            description='Stable transition identifier for preview and reporting.',
            pattern='^[a-z][a-z0-9_]*$',
        ),
    ]
    from_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    to_state_id: Annotated[str, Field(pattern='^[a-z][a-z0-9_]*$')]
    trigger: Annotated[
        Literal['scroll_progress'],
        Field(
            description='Cause of the transition. `timer` counts from state entry; `in_view_timer` counts viewable time in the current state (industry auto-collapse is N seconds in view). `media_event` fires on `video_main` playback milestones. The outcome is expressed separately by `to_state_id`.'
        ),
    ] = 'scroll_progress'
    input: Annotated[
        Literal['scroll'],
        Field(
            description='Input driving a user or scroll transition. `hover` expansion is disallowed by IAB NAP guidance and emits a LEAN policy warning visible to buyers.'
        ),
    ] = 'scroll'
    media_event: Annotated[
        MediaEvent | None,
        Field(
            description='Playback milestone of `video_main` driving a `media_event` transition (endframes, collapse-on-complete).'
        ),
    ] = None
    direction: Annotated[
        Direction | None,
        Field(
            description='Scroll direction that arms a `scroll_threshold` transition; enables direction-aware expand/collapse cycles. Re-crossing in the opposite direction does not re-fire this transition.'
        ),
    ] = Direction.down
    transition_mode: Annotated[
        Literal['scroll_linked'],
        Field(
            description='`scroll_linked` continuously interpolates the seller-owned layout between the two declared endpoint states; it is valid only with trigger `scroll_progress` and does not permit buyer scripting.'
        ),
    ] = 'scroll_linked'
    delay_ms: Annotated[
        SchemaInt | None,
        Field(
            description='For `timer`: delay after `from_state_id` activates (re-entry restarts it). For `in_view_timer`: accumulated viewable milliseconds in `from_state_id`. Timer-class transitions in a state cycle MUST declare at least 1000 (anti-strobe floor).',
            ge=0,
        ),
    ] = None
    duration_ms: Annotated[
        SchemaInt | None,
        Field(description='Duration of a seller-rendered animated transition.', ge=0),
    ] = None
    scroll_threshold_percent: Annotated[
        StrictFloat | None,
        Field(
            description='Viewport/page scroll threshold that starts a `scroll_threshold` transition.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    scroll_reference: Annotated[
        ScrollReference,
        Field(
            description='Reference frame for scroll percentages. Progress is `scroll_offset / max(scroll_extent - viewport_extent, 1) * 100`, measured on either the page document or the nearest seller-declared containing scroller.'
        ),
    ]
    scroll_start_percent: Annotated[
        StrictFloat,
        Field(
            description='Start of the bounded scroll interval for a `scroll_progress` transition.',
            ge=0.0,
            le=100.0,
        ),
    ]
    scroll_end_percent: Annotated[
        StrictFloat,
        Field(
            description='End of the bounded scroll interval for a `scroll_progress` transition. MUST be greater than `scroll_start_percent`.',
            ge=0.0,
            le=100.0,
        ),
    ]
    preserve_playback: Annotated[
        StrictBool | None,
        Field(
            description='Whether `video_main` continues without restart while the seller changes state.'
        ),
    ] = 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 delay_ms : int | None
var direction : Direction | None
var duration_ms : int | None
var from_state_id : str
var input : Literal['scroll']
var media_event : MediaEvent | None
var model_config
var preserve_playback : bool | None
var scroll_end_percent : float
var scroll_reference : ScrollReference
var scroll_start_percent : float
var scroll_threshold_percent : float | None
var to_state_id : str
var transition_id : str
var transition_mode : Literal['scroll_linked']
var trigger : Literal['scroll_progress']

Inherited members